项目以Spring MVC + Hibernate 为后台,前台通过Jquery的AJAX对象,向后台POST一个JSON对象,Spring MVC的Controller方法通过@RequestBody自动转换成POJO对象。
在测试的时候,通过httpwatch发现前台总是收到Error 400 BAD_REQUEST错误信息,并且请求时content-length始终为0.
而后台的日志则显示如下:
2013-12-31 09:47:46,700 DEBUG [13180593@qtp-459327-2] (DispatcherServlet.java:823) - DispatcherServlet with name 'SpringServlet' processing POST request for [/ma/um/saveuser.do] 2013-12-31 09:47:46,700 DEBUG [13180593@qtp-459327-2] (AbstractHandlerMethodMapping.java:220) - Looking up handler method for path /um/saveuser.do 2013-12-31 09:47:46,700 DEBUG [13180593@qtp-459327-2] (AbstractHandlerMethodMapping.java:227) - Returning handler method [public com.zhiqiang.ma.um.entity.Person com.zhiqiang.ma.um.controller.UserController.saveuser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,com.zhiqiang.ma.um.entity.Person)] 2013-12-31 09:47:46,701 DEBUG [13180593@qtp-459327-2] (AbstractBeanFactory.java:246) - Returning cached instance of singleton bean 'userController' 2013-12-31 09:47:46,701 DEBUG [13180593@qtp-459327-2] (AbstractMessageConverterMethodArgumentResolver.java:140) - Reading [class com.zhiqiang.ma.um.entity.Person] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@e9fc96] 2013-12-31 09:47:46,702 DEBUG [13180593@qtp-459327-2] (AbstractHandlerExceptionResolver.java:132) - Resolving exception from handler [public com.zhiqiang.ma.um.entity.Person com.zhiqiang.ma.um.controller.UserController.saveuser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,com.zhiqiang.ma.um.entity.Person)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No content to map to Object due to end of input; nested exception is java.io.EOFException: No content to map to Object due to end of input 2013-12-31 09:47:46,705 DEBUG [13180593@qtp-459327-2] (AbstractHandlerExceptionResolver.java:132) - Resolving exception from handler [public com.zhiqiang.ma.um.entity.Person com.zhiqiang.ma.um.controller.UserController.saveuser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,com.zhiqiang.ma.um.entity.Person)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No content to map to Object due to end of input; nested exception is java.io.EOFException: No content to map to Object due to end of input 2013-12-31 09:47:46,706 DEBUG [13180593@qtp-459327-2] (AbstractHandlerExceptionResolver.java:132) - Resolving exception from handler [public com.zhiqiang.ma.um.entity.Person com.zhiqiang.ma.um.controller.UserController.saveuser(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,com.zhiqiang.ma.um.entity.Person)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No content to map to Object due to end of input; nested exception is java.io.EOFException: No content to map to Object due to end of input 2013-12-31 09:47:46,708 DEBUG [13180593@qtp-459327-2] (DispatcherServlet.java:999) - Null ModelAndView returned to DispatcherServlet with name 'SpringServlet': assuming HandlerAdapter completed request handling 2013-12-31 09:47:46,708 DEBUG [13180593@qtp-459327-2] (FrameworkServlet.java:966) - Successfully completed request
根据日志分析得出,jquery并没有将数据发送到MappingJacksonHttpMessageConverter,所以才会报错。
多天以来度娘、谷哥给予了很大的帮助,后来发现原来是httpwatch在捣乱,将httpwatch关闭后,问题解决了。附代码仅供参考。
1.后台XML配置
<mvc:annotation-driven /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter"/> </list> </property> </bean> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> <value>application/x-www-form-urlencoded</value> </list> </property> </bean>
2.Contorller方法
@RequestMapping(value="/um/saveuser.do",method = RequestMethod.POST) public @ResponseBody Person saveuser(HttpServletRequest request,HttpServletResponse response,@RequestBody Person user){ log.debug(user.toString()); return user; }
3.前台代码
<%@ page language="java" contentType="text/html;charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script src="../script/jquery-1.10.2.min.js"></script> <script> var cfg = { type: 'POST', data: JSON.stringify({userName:'测试用户',password:'password'}), dataType: 'json', contentType:'application/json;charset=UTF-8', success: function(result) { alert(result); } }; function doTestJson(actionName){ cfg.url = actionName; $.ajax(cfg); } </script> </head> <body> <a href="#" onClick="doTestJson('saveuser.do');">jsonlogin</a> </body> </html>
参考:
http://bugs.jquery.com/ticket/12790