首页 > 解决方案 > 如何使用 Jackson 或格式错误的请求自定义 Spring Rest Controller 错误

问题描述

使用 Spring @RestController,使用 Jackson 解析请求正文中的 Json,Spring 将自动检测 json 中的错误并返回 500 响应,而请求永远不会到达您的控制器。

例子

   public class SomeRequestDetails {
       String name;

       public String getName() {}
       public void setName(String n) {}
   }
   ....

   @RequestMapping(value = "/myEndPoint", method = RequestMethod.POST,
                   produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
   public @ResponseBody ResponseEntity<SomeResponseObject> someRequest(@RequestBody SomeRequestDetails details) throws Exception {
  ....

现在,如果发布的 json 形状不正确,例如

{
   "wrongField" : "Joe"
}

Spring 将自动向客户端返回 500 响应,并将记录解释问题的堆栈跟踪。服务器日志中可能会出现像Missing required field 'name'这样的字符串。

我的问题是,有没有办法可以拦截 spring 检测到的这个错误并对返回给客户端的响应产生一些影响?

我对服务器返回 500 没问题(422 可能更准确),但最好也包括类似的东西

{
   "error" : "Missing require field 'name'"
}

作为响应主体,客户端开发人员将获得有关其请求失败原因的一些信息。

默认情况下,客户端得到一个没有正文的 500,我的服务器记录错误。这意味着客户开发人员必须与我联系以获取有关他们的请求失败原因的信息。所以我只想对错误机制进行一些控制,以便为客户端开发人员提供上下文帮助。

标签: javaspring-mvc

解决方案


您可以使用JSR-303的实现,如hibernate-validator来执行此操作。简而言之,我们需要做的是用所需的验证注释实体。例如@NotNull

import javax.validation.constraints.NotNull;

public class SomeRequestDetails {
   @NotNull
   String name;
   public String getName() {}
   public void setName(String n) {}
}

@Valid并为相应的参数使用注释:

import javax.validation.Valid;

@RequestMapping(value = "/myEndPoint", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity<SomeResponseObject> someRequest(@Valid @RequestBody SomeRequestDetails details) throws Exception {
    ...
}

如果我没记错的话,你会得到HTTP 400丢失字段的情况。如果您还想更新状态代码,您可能需要自定义@ExceptionHandler,以便按照本文建议MethodArgumentNotValidException将错误消息重新打包到ResponseEntity所需的内容中。HttpStatus

参考:


推荐阅读