最近做微信支付时候,遇到了一个支付成功之后再回调方法内部跳转的问题
首先分析一下这个问题,一般我们在做的时候,都是浏览器给我们发送来一个请求,我们服务器根据需求去转发或者是重定向
但是这里就遇到了一个问题,涉及了第三个服务器微信,这时我们怎么去跳转呢?
首先,大家都是到对于ajax来说,它只是我们用于网页于后台数据交互的一种方式,说到底它也是浏览器到服务器,但是它是由方法可以支持,服务器端去使用response来重定向的,下面我们来看一下具体的做法:
public class SessionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object handler)
throws Exception {
String requestPath = WebUtils.getPathWithinApplication(WebUtils.toHttp(servletRequest));
//String requestPath = WebUtils.getPathWithinApplication(WebUtils.toHttp
//(servletRequest)); 是转么用来获取请求路径的, 比如说说你的请求url为http://locahost:8081/WebName/account/address/add
那么获取到的路径就是/account/address/add 也就是除了web应用名称之后的那部分
因此我们可以使用这个来判断是否是登陆请求的路径
System.out.println(requestPath);
if (requestPath.equals("/login")) {
return true;
}
if(session中含有user 信息)return true
reDirect(servletRequest, servletResponse);
return false;
// 判断用户是否是访问自己的数据,比如说查看自己的订单,但是有些url是不需要进行限制的
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
// 对于请求是ajax请求重定向问题的处理方法
public void reDirect(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取当前请求的路径
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath();
// 如果request.getHeader("X-Requested-With") 返回的是"XMLHttpRequest"说明就是ajax请求,需要特殊处理
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
// 告诉ajax我是重定向
response.setHeader("REDIRECT", "REDIRECT");
// 告诉ajax我重定向的路径
response.setHeader("CONTENTPATH", basePath + "/login");
response.setStatus(HttpServletResponse.SC_ACCEPTED);
} else {
response.sendRedirect(basePath + "/login");
}
}
}
//注意:
在做重定向的时候 判断是否是ajax请求,如果是ajax请求那么就在请求头中添加 标示信息,
这个标示信息 意思是告诉前端这个是一个ajax重定向 的操作,另外需要添加一个请求头参数 是重定向请求的路径。
特别注意 response.setStatus(HttpServletResponse.SC_ACCEPTED); 这里的是指设置ajax请求的返回状态码为200, 这个状态码不可以是302,不可以是403 404等其他状态码.
前端的处理:
//设置ajax请求完成后运行的函数,
$.ajaxSetup({
complete:function(){
if("REDIRECT" == jqxhr.getResponseHeader("REDIRECT")){ //若HEADER中含有REDIRECT说明后端想重定向,
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = jqxhr.getResponseHeader("CONTENTPATH");//将后端重定向的地址取出来,使用win.location.href去实现重定向的要求
}
}
});
var jqxhr;
jqxhr= $.ajax({
type: "post",
dataType: "json",
url: "/account/address/ajax",
success: function (data) {
var data = eval("(" + data + ")");
if (data.status == 200) {
$("#" + panelId).remove();
}else{
alert(data.msg);
}
console.log(data);
}
});
意思是将当前ajax请求保存起来,然后根据请求返回的请求头中的数据判断是否需要进行重定向操作
但是上述的方法也只是ajax,我们在微信支付之后,是微信后台去交互,我们有怎么会用大ajax呢?
这就是问题的所在,所在就是,此时我们用不了浏览器去请求,如果你在后端在去重定向,你是重定向不了的,有人可能会说可能是因为我重定向的是静态资源是不能直接访问的,我试过,就算把资源放开也是不行的,关于静态资源的访问我们后面在进行接招,在这里那么你也只能重定向到当前回调方法所在类当中的其他方法 ,但是这这样又又什么用呢,你可以直接去掉方法啊,为什么要重定向,
这是因为:
异步请求的话,在后台是没办法跳,因为你相当于在页面里请求一个资源,没本法让当前页面跳转,不过可以返回一个url 在前台用window.location.href=url来跳转
因为我们这个项目是于安卓机器结合的,所以我的解决方法是,在后台收到微信支付成功的回调之后,我使用mqtt的消息服务器,去给安卓发一条,带参数的心跳信息,安卓在手到以后,又安卓在拼接参数去重定向,这就是i本人目前的解决办法,要是大家又更好的办法欢迎留言!
下面我们来说一下静态资源的访问:
首先解释一下每个文件夹的作用,如果你是用的是idea创建的springboot项目,会在项目创建的一开始resources文件夹下自动创建static以及templates文件夹。也就是说项目初始时有java、resource、static以及templates 这几个文件夹。
一般static下存放js以及css样式文件,templates存放html页面。
以上是默认会创建的文件夹以及其作用
首先static文件夹以及templates文件夹是受保护的,也就是说相当于你将文件放到了传统的ssh或ssm项目的WEB-INF下了。所以也就是说这两个文件夹下的文件是无法通过url直接访问的,以至于在springmvc下使用重定向会报404。
在讲重定向与转发之前先讲一下目录优先级的情况,webapp>META-INF/resources>resources>static>public(亲测有效)
那么如何能够直接访问到html或者css呢?
方法一
我们可以在resources下创建一个名为public的文件夹,顾名思义,放在此文件夹下的文件是共有的,可以直接通过url访问,当然也可以springmvc重定向访问啦。
方法二
在main下创建webapp文件夹,将文件放到此文件夹下,效果同上。
注!文件夹名字是固定的,起别的名字还是会报404或者无效
可以看到直接访问到是webapp下的index.html页面。因为webapp优先级大于public优先级。webapp>public
关于springmvc重定向写法
@RequestMapping(“/test1”)
public String test1(){
return “index”;
}
转发是不需要手动加html的,此时springboot发现是转发,默认配置下他会自动去templates文件夹下找到对应的文件进行转发,如果return后写的是index.html会报404。
重定向
@RequestMapping(“/test2”)
public String test2(){
return “redirect:index1.html”;
}
首先,添加redirect:这个毋庸置疑是mvc的语法问题,其次这里需要注意的是需要手动添加.html,否则会报404,而重定向则会自动去public文件夹下寻找。至于与webapp优先级别则同上述。
参考文章:
https://zhidao.baidu.com/question/428621853161398132.html https://www.jianshu.com/p/8bacc33dfde4