请求体内容缺失:org.springframework.web.method.HandlerMethod$HandlerMethodParameter。

30

在 ResponseBody 中从 JSP 传递 JSON 数据到控制器出错。

07:13:53.919 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.chaitanya.ajax.AjaxResponse com.chaitanya.web.controller.DepartmentController.addDepartment(com.chaitanya.ajax.AjaxResponse)]: 

org.springframework.http.converter.HttpMessageNotReadableException: Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter@98d8d36c
07:13:54.106 DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public com.chaitanya.ajax.AjaxResponse com.chaitanya.web.controller.DepartmentController.addDepartment(com.chaitanya.ajax.AjaxResponse)]: org.springframework.http.converter.HttpMessageNotReadableException: Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter@98d8d36c
07:13:54.125 DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.chaitanya.ajax.AjaxResponse com.chaitanya.web.controller.DepartmentController.addDepartment(com.chaitanya.ajax.AjaxResponse)]: org.springframework.http.converter.HttpMessageNotReadableException: Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter@98d8d36c
07:1

Ajax调用:

$.ajax({ 
                        url: "/BusinessReimbursment/addDepartment", 
                        method: 'POST', 
                        dataType: 'json', 
                        data: "{\"message\":\"abc\",\"success\":true}",
                        contentType: 'application/json',
                        mimeType: 'application/json',
                        success: function(data) { 
                            alert(data.id + " " + data.name);
                            commit(true);
                        },
                        error:function(data,status,er) { 
                            alert("error: "+data+" status: "+status+" er:"+er);
                        }
                    });

控制器:

@RestController
public class DepartmentController {

    @Autowired 
    @Qualifier("departmentService")
    private DepartmentService departmentService;

    @RequestMapping(value="/addDepartment", method={RequestMethod.POST})
    public @ResponseBody AjaxResponse addDepartment(@RequestBody AjaxResponse  departmentDTO){
        AjaxResponse response=new AjaxResponse();
        return response;
    }

@Bean

public RequestMappingHandlerAdapter  annotationMethodHandlerAdapter()
{
    final RequestMappingHandlerAdapter annotationMethodHandlerAdapter = new RequestMappingHandlerAdapter();
    final MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJackson2HttpMessageConverter();

    List<HttpMessageConverter<?>> httpMessageConverter = new ArrayList<HttpMessageConverter<?>>();
    httpMessageConverter.add(mappingJacksonHttpMessageConverter);

    String[] supportedHttpMethods = { "POST", "GET", "HEAD" };

    annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverter);
    annotationMethodHandlerAdapter.setSupportedMethods(supportedHttpMethods);

    return annotationMethodHandlerAdapter;
}
请帮我摆脱这个困境。 我正在使用Spring 4和jackson 2.3.0。 如果我尝试进行POST请求,则会返回:org.springframework.web.HttpRequestMethodNotSupportedException:不支持请求方法“POST”。

你能否发布AjaxResponse类的代码?另外,你的URL是“/BusinessReimbursment/addDepartment”,但你的请求映射只有“addDepartment”,这应该是“/addDepartment”还是“/BusinessReimbursment/addDepartment”? - faljbour
URL没有问题,因为它可以在没有requestBody的情况下正常工作。 - chaitanya dalvi
`public class AjaxResponse { private boolean success; private String message; public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; }}` - chaitanya dalvi
7个回答

34

在HTTP GET请求中,不应该发送请求正文。您应该修改addDepartment()以仅支持POST,并将JSON POST到该端点。如果您想获取有关部门的信息,则应创建一个单独的控制器方法来执行此操作(而且不需要请求正文)。

另外,请仔细检查您的端点定义,因为您在$.ajax调用中拼写错误了“reimbursement”。


在请求映射注释中,我提到了GET和POST。如果我传递post响应,那么它会给出我在post中提到的错误。 - chaitanya dalvi
1
请再次阅读我的回答。您不能在@RequestMapping注释中同时使用GET@RequestBody,因为GET请求不能有正文。通常情况下,GET应仅用于只读操作,例如获取记录或搜索。完全删除GET并重试。 - ach
你不能在HTTP GET请求中发送请求正文,这是从什么时候开始的?更多信息请参见:https://dev59.com/53NA5IYBdhLWcg3wZ85S - JackTheKnife
我在4年前的答案中说错了。如果你想提交编辑,并将“不能”改为“不应该”,请随意。 - ach
@ach 实际上,在某种程度上你是正确的。Spring框架的RestTemplate如果请求是GET,即使HTTP规范不再禁止这样做,它也会丢弃消息体。我在源代码中清楚地看到了这一点。 - Zhou
显示剩余3条评论

19

我也遇到过相同的问题。我使用 "Postman" 进行 JSON 请求。代码本身没有问题。我只是将内容类型设置为 JSON (application/json),就像您在下面的图片中看到的那样,它就起作用了。

My Code


这是一个问题吗?如果是的话,请将其作为单独的问题发布。如果需要,您可以添加到此问题的链接。 - default locale
下一次,请不要将整个帖子变成链接,最好在末尾添加链接。另外,楼主没有提到 Postman。如果你想解决这个问题,最好展示具体的错误以及如何重现它。 - default locale

5

尝试这样写:

@RequestBody(required = false) String str

@RequestBody注解用于绑定HTTP请求中的请求体到一个方法参数上,"required=false"表示该请求体可选,即可以为空。


3
不,这可能没有帮助。 - Alexander
我不明白为什么这个有效了,但它确实起作用了,我的请求主体经过了之前未能实现... - AylaWinters
@Juan 这与根本不使用注释是一样的,它仍然可以工作,但并不是解决方案。 - Harsh Gundecha

3

我对您的代码进行了一些小修改,并在我拥有的一个Spring项目中进行了测试,它可以正常工作。如果我使用GET,则逻辑仅适用于POST,它将抛出无效请求错误。此外,在您的ajax调用中,我注释掉了commit(true),浏览器调试器标记出了一个错误,即它未定义。只需修改URL以适应您的Spring项目架构即可。

 $.ajax({ 
                    url: "/addDepartment", 
                    method: 'POST', 
                    dataType: 'json', 
                    data: "{\"message\":\"abc\",\"success\":true}",
                    contentType: 'application/json',
                    mimeType: 'application/json',
                    success: function(data) { 
                        alert(data.success + " " + data.message);
                        //commit(true);
                    },
                    error:function(data,status,er) { 
                        alert("error: "+data+" status: "+status+" er:"+er);
                    }
                });



@RequestMapping(value="/addDepartment", method=RequestMethod.POST)
  public AjaxResponse addDepartment(@RequestBody final AjaxResponse  departmentDTO)
  {
    System.out.println("addDepartment: >>>>>>> "+departmentDTO);
    AjaxResponse response=new AjaxResponse();
    response.setSuccess(departmentDTO.isSuccess());
    response.setMessage(departmentDTO.getMessage());
    return response;
  }

1
抱歉各位...实际上,由于需要CSRF令牌,我才遇到了这个问题。我已经实现了Spring Security并启用了CSRF。通过Ajax调用,我需要传递CSRF令牌。

Request method 'POST' not supported Invalid CSRF token found for http://localhost:8080/BusinessReimbursment/addDepartment DispatcherServlet with name 'dispatcher' processing POST request for [/BusinessReimbursment/403] Looking up handler method for path /403 HttpRequestMethodNotSupportedException: Request method 'POST' not supported HttpRequestMethodNotSupportedException: Request method 'POST' not supported HttpRequestMethodNotSupportedException: Request method 'POST' not supported WARN o.s.web.servlet.PageNotFound - Request method 'POST' not supported – - chaitanya dalvi

1
在我的情况下,可能是因为POSTMAN的设置问题,但我不知道原因,可能是我从其他地方复制了一个查询。我只需在POSTMAN中创建一个新请求并运行它即可解决问题。

0
如果在Postman中可以正常工作,尝试使用新的Spring版本,因为“org.springframework.boot”2.2.2.RELEASE版本可能会抛出“需要请求体内容”的异常。
请尝试使用2.2.6.RELEASE版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接