spring-boot-validate服务中的数据

m528fe3b  于 2021-07-22  发布在  Java
关注(0)|答案(1)|浏览(302)

我需要在spring引导应用程序的服务中执行dto的手动验证。在验证错误的情况下,抛出自定义异常还是constraintviolationexception更好?
在constraintviolationexception的情况下,如何抛出它?

t3psigkw

t3psigkw1#

我会坚持使用验证注解和constraintviolationexception来保持代码和验证尽可能简单。
有许多选项取决于您计划如何进行验证,但在类似的情况下,我使用的方法是创建一个注解和一个验证器,就像controller中的任何验证注解一样使用。
验证内容如下所示:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyValidatorAnnotation.MyValidator.class)
public @interface MyValidatorAnnotation {
    String message() default "not a valid DTO";
    Class<? extends Payload>[] payload() default {};
    Class<?>[] groups() default {};
    // I have created this validator as interface's inner class to
    // to keep code simpler but it can be "outer" class also.
    @Component // this is not necessarily needed
    class MyValidator
            implements ConstraintValidator<MyValidatorAnnotation, MyDto> {
        @Resource
        private MyRepository myRepository;
        @Override
        public boolean isValid(MyDto myDto, ConstraintValidatorContext context) {
            boolean valid = true;
            // If you need some custom messages, try something like:
            context.disableDefaultConstraintViolation();
            if (StringUtils.isBlank(myDto.getName())) {
                context.buildConstraintViolationWithTemplate("NAME WAS BLANK")
                        .addPropertyNode("name")
                        .addConstraintViolation();
                valid = false;
            }
            // Any checks you need to do with myRepository
            // or with any other resources
            return valid;
        }
    }
}

那么使用/触发这个验证依赖于几件事。请参见下面的服务示例:

@Service
@Validated
public class MyService {
    // In this method validation will not work if called from MyService itself.
    // Works only when called from "outside" so from any other managed bean
    public void handleMyDtoExt(@Valid MyDto myDto) {
        // furious handling
    }
    // Works when called anywhere even from service itself.
    // The drawback is that you need more code & injection & testing which you of
    // course want to avoid.
    // In this case you also might not want add @Validated to your service.
    @Resource
    private Validator validator;
    private void handleMyDto(MyDto myDto) {
        Set<ConstraintViolation<MyDto>> cvs = validator.validate(myDto);
        if(!cvs.isEmpty()) {
            throw new ConstraintViolationException(cvs);
        }
        // furious handling
    }
}

相关问题