Spring中的自定义Javax注释错误处理

你好! 在本文中,我将介绍如何覆盖默认的异常处理程序方法MethodArgumentNotValidException which is thrown when Java Bean Validation Annotations are violated.<!--more-->

What is Java Bean Validation?

Java Bean Validation is a specification that is defined in ĴSR-380. It makes possible defining constraints with annotations, write custom constraints, etc. I will use Hibernate Validator since it is the only certified implementation of Bean Validation 2.0. It’s not a requirement to use with Spring but I’m going to implement it with Spring Boot because of its popularity. I will not explain how to use these annotations however you can find it in one of my articles.

Create a Simple Project and Provide Some Annotations

使用Spring Initializr创建一个项目,然后选择Web和Lombok依赖项。 因为网络启动器包括Hibernate Validator。 然后创建一个名为User的类,如下所示。

@Data
public class User {  

    @Length(min = 2, max = 30, message = "Name must be between 2-30 characters. ")  
    @Pattern(regexp = "^[a-zA-Z]+(([',. -][a-zA-Z])?[a-zA-Z]*)*$", message = "Name is invalid.")  
    private String name;  

    @Length(min = 2, max = 30, message = "Surname must be between 2-30 characters.")  
    @Pattern(regexp = "^[a-zA-Z]+(([',. -][a-zA-Z])?[a-zA-Z]*)*$", message = "Surname is invalid.")  
    private String surname;  

    @Email(message = "Enter a valid email address.")  
    private String email;  

使用外部消息源处理错误消息会更好,但是我没有使用它,因为它会使本文更长。

然后创建一个RestController并接受User作为@有效输入。

@RestController  
@RequestMapping("/api/users")  
public class UserRestController {  

    @PostMapping  
    public ResponseEntity<User> saveUser(@Valid @RequestBody User user) {  

        return ResponseEntity.ok(user);  
    }  
}
不要忘记使用@有效注解。 因为它可以确保带注释的参数得到验证。

运行该应用程序并发送示例请求。 (当然,您不必使用cURL。我通过Postman发送了此请求。您可以复制此内容并将其作为原始文本导入到Postman。)

curl --location --request POST 'http://localhost:8080/api/users' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Marion",
    "surname": "Cotillard",
    "email": "marion@cotillard.com",
    "birthdate": "1975-09-30"
}'

如预期的那样,此请求将返回200。 现在,让我们打破一些规则:

curl --location --request POST 'http://localhost:8080/api/users' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "M",
    "surname": "Cotillard",
    "email": "marion@cotillard.com",
    "birthdate": "1975-09-30"
}'

我刚摔坏@长度统治名称领域。 该请求的回复很长:

{
  "timestamp": "2020-02-01T21:27:06.935+0000",
  "status": 400,
  "error": "Bad Request",
  "errors": [
    {
      "codes": [
        "Length.user.name",
        "Length.name",
        "Length.java.lang.String",
        "Length"
      ],
      "arguments": [
        {
          "codes": [
            "user.name",
            "name"
          ],
          "arguments": null,
          "defaultMessage": "name",
          "code": "name"
        },
        30,
        2
      ],
      "defaultMessage": "Name must be between 2-30 characters. ",
      "objectName": "user",
      "field": "name",
      "rejectedValue": "M",
      "bindingFailure": false,
      "code": "Length"
    }
  ],
  "message": "Validation failed for object='user'. Error count: 1",
  "path": "/api/users"
}

这可能是一个令人困惑的响应,但是可以创建自定义响应。

Override Exception Handler

首先,为自定义响应创建一个POJO。

@Getter  
@Setter  
@Builder  
@AllArgsConstructor  
public class CustomFieldError {  

    private String field;  

    private String message;  

}

您可以添加其他字段,但这足以满足本文的要求。 然后创建一个异常处理程序方法:

@ExceptionHandler(MethodArgumentNotValidException.class)  
public final ResponseEntity<Object> handleUserMethodFieldErrors(MethodArgumentNotValidException ex, WebRequest request) {  
    // some logic
}

Javax注释抛出MethodArgumentNotValidException.class因此,请覆盖此异常。 在该方法中,提取字段错误并创建CustomFieldError来自他们的对象。

final List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();    

final List<CustomFieldError> customFieldErrors = new ArrayList<>();  

for (FieldError fieldError : fieldErrors) {  

    final String field = fieldError.getField();  

    final String message = fieldError.getDefaultMessage();  

    final CustomFieldError customFieldError = CustomFieldError.builder().field(field).message(message).build();  

    customFieldErrors.add(customFieldError);  

}

你也可以得到被拒绝的值和错误代码. Then create an HTTP response和return.

return ResponseEntity.badRequest().body(customFieldErrors);

再次运行该项目并发送相同的请求。 这将在下面的正文中返回400响应:

[
    {
        "field": "name",
        "message": "Name must be between 2-30 characters. "
    }
]

您可以自定义此响应或使用相同的方法覆盖类似的异常处理程序。

Github Repo: https://github.com/kamer/custom-javax-annotation-error-handling


如有任何疑问,建议或更正,请随时与我联系:

Ëmail: kamer@kamerelciyar.com
Twitter: https://twitter.com/kamer_ee

from: https://dev.to//kamer/custom-javax-annotation-error-handling-in-spring-5a03

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值