首页 > 解决方案 > 嵌套类的自定义验证器并将错误发送回控制器

问题描述

我正在使用 Java 验证和 Spring。我有几个需要验证设置的类。在验证每个类的简单字段时,我的验证器工作正常。但是,一个类的字段包含我需要验证的其他两个类的列表,其中一个包含我需要验证的其他两个类的列表。

我找到了一种让它工作的方法,但它有点混乱并且需要(我认为)我的控制器中有太多额外的代码。例如,我在验证中创建了一个单独的方法来验证 A 类的列表:

    public Errors validateClassA(ClassA classA){
        List<ClassB> classBs = classA.getScanResults().getClassesToValidate();
            for (ClassB classB : classBs) {
                Errors error = new BeanPropertyBindingResult(classB, "ClassB");
                classBValidator.validate(classB, error);
                if(error.hasErrors()){
                    return error;
                }
            }
            return null; 
        }

这仅用于测试,但我不想传回空值,而且看起来有点乱。这是我的控制器使用此代码的部分:

 classAValidator.validate(classA, bindingResult);
 Errors classBErrors = classAValidator.validateClassB(classA);
 if (bindingResult.hasErrors()) {
     classAValidator.logErrors(bindingResult);
     return new ResponseEntity<GenericServiceResponse<Void>>(new GenericServiceResponse<Void>(FAIL, bindingResult.toString()), HttpStatus.BAD_REQUEST);
 }
 if(classBErrors.hasErrors()){
     classAValidator.logErrors(classBErrors);
     return new ResponseEntity<GenericServiceResponse<Void>>(new GenericServiceResponse<Void>(FAIL, classBErrors.toString()), HttpStatus.BAD_REQUEST);
 }           

感觉就像我让这比它需要的更复杂,但我不知道如何处理它。简要浏览一下 Errors 类的文档,似乎有一些方法可以为错误设置嵌套路由,但我似乎找不到很多这样的例子,所以我不确定它是否适用于我的情况。希望所有这些都有意义,并感谢您的任何建议。

标签: javaspringvalidation

解决方案


是的,你让这个问题变得更加复杂,它需要:) 你不需要自己实现这些功能 - Spring 为你做。

假设您有一个简单的 DTO,如下所示:

public class SomeDTO {

   public static class SomeOtherDTO {

      @NotEmpty
      private String someOtherField;

   }

   @NotNull
   private SomeOtherDTO someField;

}

@RestController使用方法:

@RequestMapping(value = "/someEndpoint", method = RequestMethod.POST)
public ResponseEntity<HttpStatus> someEndpoint(@Valid @RequestBody SomeDTO dto) {
    return new ResponseEntity<>(HttpStatus.OK);
}

这就是全部 -dto现在将由 Spring 验证 - 您所要做的就是自己处理潜在的错误。你可以用很多不同的方式来做。我的建议是使用@ControllerAdvice- 这样您就可以对所有已注册@Controller的 s 进行统一的验证错误处理:

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException exception, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // here you have access to the errors via exception argument - do with them whatever you want
    }
}

推荐阅读