Spring 启动 - 验证服务中的数据
Spring boot - Validate data in service
我需要在我的 Spring 引导应用程序的服务中执行 DTO 的手动验证。如果出现验证错误,是抛出自定义异常还是抛出 ConstraintViolationException 更好?
在 ConstraintViolationException 的情况下,我该如何抛出它?
我会坚持使用验证注释和 ConstraintViolationException 来使代码和验证尽可能简单。
根据您计划如何进行验证,有很多选项,但我使用 - 在类似情况下 - 一种创建注释和验证器的方法,它们与控制器中的任何验证注释一样使用,例如.
验证内容如下所示:
@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;
}
}
}
然后 using/triggering 此验证取决于几件事。请参阅以下服务示例:
@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
}
}
我需要在我的 Spring 引导应用程序的服务中执行 DTO 的手动验证。如果出现验证错误,是抛出自定义异常还是抛出 ConstraintViolationException 更好?
在 ConstraintViolationException 的情况下,我该如何抛出它?
我会坚持使用验证注释和 ConstraintViolationException 来使代码和验证尽可能简单。
根据您计划如何进行验证,有很多选项,但我使用 - 在类似情况下 - 一种创建注释和验证器的方法,它们与控制器中的任何验证注释一样使用,例如.
验证内容如下所示:
@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;
}
}
}
然后 using/triggering 此验证取决于几件事。请参阅以下服务示例:
@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
}
}