1.引言
大多数时候,spring validation框架提供的校验规则都能够满足我们的业务需求。有时候我们也需要一些特殊的业务校验,如果框架不能满足,我们该如何处理呢?
这个事情处理起来还是很简单的,通常情况下,一个框架除了提供通用处理能力外,还有一个指标是很重要的:扩展性。因此spring validation框架给我们提供了一些扩展的能力,方便我们处理特殊业务校验场景。
事实上真正提供了扩展点的是validation-api规范中提供的,我们只需要完成两件事
- 自定义一个注解
- 自定义一个校验器,实现接口javax.validation.ConstraintValidator
这样一来,我们就可以完美的处理特殊业务校验场景。
2.案例
这里,我们案例假定有一个业务Id的特殊业务场景,需要校验参数Id满足规则
- 由a-f,以及0-9组成的字符串
- 长度在6-10位之间
我们来看一下,如何通过自定义校验规则来处理。
2.1.自定义校验注解
java
/**
* 自定义校验Id注解
*/
@Target({ElementType.METHOD, ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {CustomIdValidator.class})
public @interface CustomIdValid {
/**
* 提示消息
* @return
*/
String message() default "Id不满足业务规则";
/**
* 分组
* @return
*/
Class<?>[] groups() default {};
/**
* 负载
* @return
*/
Class<? extends Payload>[] payload() default {};
}
2.2.自定义校验器
java
/**
* 自定义Id校验器
*
* @author ThinkPad
* @version 1.0
*/
public class CustomIdValidator implements ConstraintValidator<CustomIdValid,String>{
/**
* 定义Id校验规则,这里我们假定Id规则为:
* 1.由0-9的数字,以及a-f的字符组成
* 2.长度允许6-10位
*/
private final static Pattern ID_PATTERN = Pattern.compile("^[a-f\\d]{6,10}$");
/**
* 重写校验方法
* @param s
* @param constraintValidatorContext
* @return
*/
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
// 如果值为空,则不进行校验,直接返回true(校验通过)
if(s == null){ return true;}
// 通过正则表达式方式校验
Matcher matcher = ID_PATTERN.matcher(s);
return matcher.find();
}
}
2.3.验证
java
/**
* 自定义校验规则,验证校验Id
* @param customId
* @return
*/
@RequestMapping("/custom/{customId}")
public String validCustomId(@PathVariable("customId") @CustomIdValid String customId){
log.info("接收到customId:{}", customId);
return "ok";
}
参数满足校验规则:校验通过
参数不满足校验规则:校验不通过