最近使用validation遇到一个问题,a对象的参数验证根据某个属性的不同而有不同的规则。而此时使用原有注解规则显然不能实现,在参考此文章后写此篇。
思路是通过自定义注解和自定义比较器实现。
1.自定义注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
@Constraint(validatedBy = JudgeArticleOptionValidator.class)
public @interface JudgeArticleOption {
String message() default "参数异常,请检查后再试";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2.自定义比较器,实现ConstraintValidator接口,并在isValid()中实现自定义逻辑,其中s的值通过自定义注解由被校验对象提供
public class JudgeArticleOptionValidator implements ConstraintValidator<JudgeArticleOption, String> {
@Override
public void initialize(JudgeArticleOption constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
String[] params = s.split(ArticleDto.SPLIT_TAG);
boolean tag=true;
if (params[0].equals("null")){
//保存
for (int i = 1;i<params.length;i++){
if (params[i].equals("null")){
tag=false;
break;
}
}
return tag;
}else{
//新增
for (int i = 1;i<params.length;i++){
if (!params[i].equals("null")){
tag=true;
break;
}
}
return !tag;
}
}
}
3.在需要校验的对象中定义一个传入需要校验属性的值的方法
4.在接口中加入@Validated注解就会开启对参数的校验
5.当自定义校验器返回值为false时validation就会抛出MethodArgumentNotValidException异常,可以设置全局异常捕获,并返回预期值
ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result MethodArgumentNotValidExceptionHandle(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
String msg =null;
if (bindingResult.hasErrors()){
List<ObjectError> allErrors = bindingResult.getAllErrors();
if (allErrors!=null){
msg = allErrors.get(0).getDefaultMessage();
}
}
return Result.validatedException(msg);
}
6.测试请求,可以看到传入参数在经过校验后不符合我自定义的规则,所以会抛出异常。