当前位置: 代码迷 >> 综合 >> Spring MVC @RequestBody 400/415错误和几种$.ajax格式
  详细解决方案

Spring MVC @RequestBody 400/415错误和几种$.ajax格式

热度:42   发布时间:2023-12-17 00:56:42.0

在一个Controller里面加了@RequestBody注解

    @PostMapping("/test")public Map<String, Object> test(@RequestBody User user) {System.out.println("test");return new DataReturnMap("user", user).getMap();}

而Ajax代码如下:

<script>$(document).ready(function () {
     var user = {
    "username":"Jia", "email":"123456", "industry":1, "corporation":"hust"};$.ajax({type:"POST",url:"user/test",dataType:"json",contentType:"application/json",data:user,success:function (data) {
     },error:function (err) {
     }});}); </script>

在之后发现接收不到数据,报400的错误:

2016-11-30 10:31:16 DEBUG ServletInvocableHandlerMethod:167 - Error resolving argument [0] [type=com.iot.baobiao.jooq.tables.pojos.User]
HandlerMethod details: 
Controller [com.iot.baobiao.controller.UserController]
Method [public java.util.Map<java.lang.String, java.lang.Object> com.iot.baobiao.controller.UserController.test(com.iot.baobiao.jooq.tables.pojos.User)]org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Unrecognized token 'username': was expecting ('true', 'false' or 'null')at [Source: java.io.PushbackInputStream@1a0b7981; line: 1, column: 10]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'username': was expecting ('true', 'false' or 'null')at [Source: java.io.PushbackInputStream@1a0b7981; line: 1, column: 10]at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:227)at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:212)at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:197)at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:149)at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:127)at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

在浏览器里面查看之后截图如图所示:

这里写图片描述

可以看到,发送的请求头的Content-Typeapplication/json,但是数据的格式是用&符号连接起来的。

修改一下Ajax代码:

<script>$(document).ready(function () {
     var user = {
    "username":"Jia", "email":"123456", "industry":1, "corporation":"hust"};$.ajax({type:"POST",url:"user/test",dataType:"json", // contentType:"application/json", // data:JSON.stringify(user),data:user,success:function (data) {
     },error:function (err) {
     }});}); </script>

这次的错误是415,表示不支持这种Media Type,在浏览器里面查看的截图如下:

这里写图片描述

可以看到此时的Content-Typeapplication/x-www-form-urlencoded,数据的格式是表格的形式。

再次修改Ajax代码,这次把需要发送的数据用JSON.stringify函数处理一下:

<script>$(document).ready(function () {
     var user = {
    "username":"Jia", "email":"123456", "industry":1, "corporation":"hust"};$.ajax({type:"POST",url:"user/test",dataType:"json",contentType:"application/json",data:JSON.stringify(user),success:function (data) {
     },error:function (err) {
     }});}); </script>

这次没有错误了,而且在Spring的Controller里面也接收到了一个User对象,此时的浏览器截图如下:

这里写图片描述

可以看到,这次的Content-Typeapplication/json,而发送的数据也变成了JSON对象的格式,所以Spring MVC的Jackson2HttpMessageConverter才能正确地解析。

总而言之,必须把Content-Type设置成application/json,因为@RequestBody注解不支持默认的application/x-www-form-urlencoded格式的数据。另外需要把数据用JSON.stringify函数处理一下,转换成JSON对象的格式(虽然把Content-Type设置成application/x-www-form-urlencoded的同时也能用JSON.stringify函数把数据转换成JSON对象的格式,但是还是会报415这个错误)。还有,Content-Type用来修改请求头,而发送的数据格式和请求头没有必然关系,数据格式还是需要用JSON.stringify函数来设置!!

另外,在这种情况下如果需要用Postman这个工具来测试的话,可以在Headers里面把Content-Type设置成application/json,再把Body这个选项设置成raw格式,并填写数据,如图:

这里写图片描述

  相关解决方案