在学习springMVC时想在前端使用ajax请求访问controller方法,该方法返回一个自定义实体类的数据作为响应传递给ajax,ajax弹出响应的数据。结果没有正确弹出想要的结果。
代码如下:
$("#testResponseBody2").click(function () {
$.ajax({
url: "user/testResponseBody2", // 请求路径
contentType: "application/json;charset=UTF-8",
data: '{"message":"通过前端ajax发送了一个字符串","length":23}',
dataType: "json",
type: "post",
success: function (data) {
alert(data); //显示[object Object],因为alert不能弹出对象
alert("message: "+data.message);
console.log(data); //F12在调试界面的控制台可以显示对象json表示的字符串
},
error: function () {
alert("出错啦...");
}
});
});
------------------------------------------------------------------------------------
<input type="button" value="testResponseBody2" id="testResponseBody2"><br><br>
------------------------------------------------------------------------------------
@RequestMapping("/testResponseBody2")
@ResponseBody
public Message testResponseBody2(@RequestBody Message message) {
//要想使用ResponseBody注解,不仅要导入jackson的依赖,还需要給自定义类加入get方法。
System.out.println(message);
message.setMessage("被java程序更改了传来的信息");
return message;
}
经过分析和测试,发现是配置的拦截器导致的冲突。当有拦截器作用于使用上述的testResponseBody2方法时,就会导致无法的得到想要的效果:弹出正确的信息。
下面通过实际测试来分析@ResponseBody注解和拦截器冲突的问题。
前端:
$("#testResponseBody3").click(function () {
$.ajax({
url: "user/testResponseBody3", // 请求路径
contentType: "application/json;charset=UTF-8",
data: '{"message":"通过前端ajax发送了一个字符串","length":23}',
dataType: "json",
type: "post",
success: function (data) {
alert(data); //显示[object Object],因为alert不能弹出对象
alert("message: "+data.message);
console.log(data); //F12在调试界面的控制台可以显示对象json表示的字符串
},
error: function () {
alert("出错啦...");
}
});
});
---------------------------------------------------------------------------------------------------
<h1>测试ajax请求和a标签请求@ResponseBody的响应时,能否成功响应,以及拦截器能否拦截下来转发到其他页面h1>
<form action="user/testResponseBody2">
message: <input type="text" name="message"><br>
length: <input type="text" name="length"><br>
<input type="submit" value="submit">
form>
<a href="user/testResponseBody2?message=aaa&length=111">testResponseBody:测试ResponseBody和拦截器的冲突问题a><br><br>
<input type="button" value="testResponseBody3" id="testResponseBody3"><br><br>
Controller方法:
@RequestMapping("/testResponseBody2")
@ResponseBody
public Message testResponseBody2(Message message) {
System.out.println(message);
message.setMessage("被java程序更改了传来的信息");
return message;
}
@RequestMapping("/testResponseBody3")
@ResponseBody
public Message testResponseBody3(@RequestBody Message message) {
System.out.println(message);
message.setMessage("被java程序更改了传来的信息");
return message;
}
拦截器类:
//测试拦截器的前置方法在ajax和a标签两种访问情况下能否拦截@ResponseBody的响应跳转其他页面
public class TestInterceptorPreHandle_ResponseBody implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截成功,执行拦截器前置方法");
request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
return false;
}
}
//测试拦截器的后置方法在ajax和a标签两种访问情况下能否拦截@ResponseBody的响应跳转其他页面
public class TestInterceptorPostHandle_ResponseBody implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截成功,执行拦截器前置方法");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("执行拦截器后置方法");
modelAndView.addObject("attributeName1","拦截器后置方法设置此EL");
response.sendRedirect("/springMVC02/testForward&Redirect.jsp");
}
}
springMVC.xml中配置拦截器的作用方法:每次只引入一个拦截器类作用于testResponseBody2和3方法,即第一次测试引入TestInterceptorPreHandle_ResponseBody拦截器作用于testResponseBody2和3方法,第二次测试引入TestInterceptorPostHandle_ResponseBody拦截器作用于testResponseBody2和3方法。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/testResponseBody2"/>
<bean class="liang.interceptor.TestInterceptorPreHandle_ResponseBody">bean>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/testResponseBody3"/>
<bean class="liang.interceptor.TestInterceptorPreHandle_ResponseBody">bean>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/testResponseBody2"/>
<bean class="liang.interceptor.TestInterceptorPostHandle_ResponseBody">bean>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/testResponseBody3"/>
<bean class="liang.interceptor.TestInterceptorPostHandle_ResponseBody">bean>
mvc:interceptor>
mvc:interceptors>
测试结果:
拦截器使用前置方法跳转其他页面
拦截器使用后置方法跳转其他页面
此外就算拦截器没有跳转其他页面的操作,只要有拦截器就会导致ajax无法接收到响应数据。而不加拦截器就可以正确弹出响应数据。
分析: