Spring boot rest api:如果请求Body以不正确的格式发送,如何正常响应?

Tei*_*raz 1 java rest spring spring-boot

假设我们有Spring boot api端点:

调节器

...
public String registerUser(@RequestBody @Valid User user) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

用户

class User {
   @NotNull
   private Integer age;

   @NotNull
   private String name; 
   ...
}
Run Code Online (Sandbox Code Playgroud)

例如,当我发送一个缺少字段的请求时,agespring会回复一条很好的消息,说明age属性路径中缺少param,例如:

{
  "timestamp": "2016-12-20T18:44:29.450+0000",
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
  "errors": [
    {
      "defaultMessage": "may not be nullt",
      "objectName": "user",
      "field": "age",
      ...
Run Code Online (Sandbox Code Playgroud)

但是如果我age在请求中提供param作为String:

{
   age: "somestring"
}
Run Code Online (Sandbox Code Playgroud)

我得到org.springframework.http.converter.HttpMessageNotReadableException... Could not read document: Can not deserialize value of type java.lang.Integer from String有哪些方法的信息,排除了这个异常(我不想透露).

但有没有办法以像失踪年龄的格式回应这样的例外?

就像是:

"errors": [
        {
          "defaultMessage": "incorrect format",
          "objectName": "user",
          "field": "age",
          ...
Run Code Online (Sandbox Code Playgroud)

Ada*_*dam 5

您将需要一个@ControllerAdvicebean来捕获该异常并适当地处理它.从https://blog.jayway.com/2013/02/03/improve-your-spring-rest-api-part-iii/,代码可能如下所示:

@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Throwable mostSpecificCause = ex.getMostSpecificCause();
        ErrorMessage errorMessage;
        if (mostSpecificCause != null) {
            String exceptionName = mostSpecificCause.getClass().getName();
            String message = mostSpecificCause.getMessage();
            errorMessage = new ErrorMessage(exceptionName, message);
        } else {
            errorMessage = new ErrorMessage(ex.getMessage());
        }
        return new ResponseEntity(errorMessage, headers, status);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您可以修改响应以满足您的需求.