【问题标题】:Custom generic request validator in Spring bootSpring boot 中的自定义通用请求验证器
【发布时间】:2019-08-25 18:26:41
【问题描述】:

我是 Spring Boot 新手,我对请求字段验证有疑问。 我想出了如何在字段级别使用注释来指定自定义错误消息:

public class EmployeeRequest {

    @NotEmpty( message = "field name cannot be empty" )
    @NonNull
    private String name;

    @NotEmpty( message = "field address cannot be empty" )
    @NonNull
    private String address;
}

但是为了使用这些注释,我必须为每个请求类中的每个字段指定错误消息。 另外由于某种原因,我得到的回复不是很整洁:

"org.springframework.validation.BeanPropertyBindingResult: 1 errors\nField error in object 'employeeRequest' on field 'name': rejected value [null]; codes [NotEmpty.employeeRequest.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeeRequest.name,name]; arguments []; default message [name]]; default message [provide a name]"

假设所有字段都必须是NotEmptyNonNull,是否有更优雅和通用的方法来对每个请求进行此类字段验证?

public class EmployeeController {

    @PostMapping("/test")
    @ResponseBody
    public EmployeeResponse testMethod(@RequestBody EmployeeRequest request) {
        genericFieldsValidatorForAllRequests(request);
        doSomeStuffIfRequestIsValid(request);
}

谁能提供一些想法如何实现该请求验证器?

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    你好像问了两个问题,希望我能同时回答。

    为什么 JSON 响应看起来“不太整洁”?

    默认情况下,Spring Boot 会捕获 Web 请求处理程序中抛出的任何未捕获的异常(例如 @RequestMapping@GetMapping 等),并将其转换为以下结构的 JSON 响应:

    {
     "timestamp": 1500597044204,
     "status": 400,
     "error": "Bad Request",
     "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
     "message": "JSON parse error: Unrecognized token .....",
     "path": "/birds"
    }
    

    让您的错误响应 JSON 看起来不同的一种方法是创建一个异常处理程序。基本上,您可以在它们进入 Spring Boot 的默认错误处理程序之前捕获您想要的错误。为此,您可以在与控制器相同或更高级别的包中的某处制作其中之一:

    @ControllerAdvice
    public class GlobalErrorHandler {
    
        @ExceptionHandler(ExceptionICareAbout.class)
        public MyErrorResponseObject handleExceptionICareAbout(ExceptionICareAbout e) {
            return new MyErrorResponseObject(<ADD CODE HERE>)
        }
    
    }
    

    在您的情况下,您可以为MethodArgumentNotValidException 创建一个异常处理程序并将其转换为您喜欢的错误响应。 (我相信这是 JSR303 注释验证失败时引发的异常,但请仔细检查我)

    您还可以将错误响应对象包装在 Spring 提供的 ResponseEntity&lt;&gt; 对象中以自定义响应中的其他内容,或者仅使用 @ResponseStatus 注释异常处理程序方法以仅自定义返回的 http 状态代码。

    另外,如果你想捕获每一个异常并阻止它们进入 Spring Boot 的默认异常处理程序,只需为 Exception 类本身创建一个异常处理程序,例如 @ExceptionHandler(Exception.class)

    是否有更“优雅和通用”的方式来进行字段验证?

    像你一样使用JSR303 注释(@NotNull@Size 等...)结合@Valid 注释在你关心的每个对象上的每个字段是我知道的最好方法。我会花时间思考重用代码和错误消息的方法,但这就是我能想到的全部。也许我们可以在 cmets 中得到一些好的答案。

    Spring 确实提供了这些 Validators 来代替 JSR303 注释,但我对它们没有太多经验。

    【讨论】:

      猜你喜欢
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      相关资源
      最近更新 更多