一吧兔、通點(diǎn)磷仰?
比如訂單狀態(tài)、性別掩驱、用戶類型等枚舉參數(shù)芒划,在作值有效性校驗(yàn)時,我們可不可以使用 validator 統(tǒng)一在controller層進(jìn)行處理呢欧穴?
二民逼、實(shí)現(xiàn)方案
1. 定義枚舉值數(shù)組獲取接口
public interface IntArrayValuable {
int[] array();
}
2. 定義用戶枚舉類型,并實(shí)現(xiàn)IntArrayValuable 接口
public enum UserTypeEnum implements IntArrayValuable {
USER(1, "用戶"),
ADMIN(2, "管理員");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(UserTypeEnum::getValue).toArray();
/** 類型 */
private final Integer value;
/** 類型名 */
private final String name;
UserTypeEnum(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
@Override
public int[] array() {
return ARRAYS;
}
}
3. 定義 UserVo
public class UserVo {
@NotEmpty(message = "用戶名不能為空")
@Length(min = 4, max = 16, message = "用戶名不能為空 4-16 位")
@Pattern(regexp = "^[0-9]+$", message = "用戶名全部為數(shù)字")
private String name;
@Mobile()
private String mobile;
/** 用戶類型 */
@NotNull(message = "用戶類型不能為空")
@InEnum(value = UserTypeEnum.class, message = "用戶類型必須是 {value}")
private Integer userType;
//.....省略set get 方法
}
4. 定義InEnum注解
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = InEnumValidator.class
)
public @interface InEnum {
/**
* @return 實(shí)現(xiàn) EnumValuable 接口的
*/
Class<? extends IntArrayValuable> value();
String message() default "必須在指定范圍 {value}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
5. 定義 InEnumValidator 驗(yàn)證器
public class InEnumValidator implements ConstraintValidator<InEnum, Integer> {
private List<Integer> values;
@Override
public void initialize(InEnum annotation) {
IntArrayValuable[] values = annotation.value().getEnumConstants();
if (values.length == 0) {
this.values = Collections.emptyList();
} else {
this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList());
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
// 為空時涮帘,默認(rèn)不校驗(yàn)拼苍,即認(rèn)為通過
if (value == null) {
return true;
}
// 校驗(yàn)通過
if (values.contains(value)) {
return true;
}
// 校驗(yàn)不通過,自定義提示語句(因?yàn)榈饔В⒔馍系?value 是枚舉類疮鲫,無法獲得枚舉類的實(shí)際值)
context.disableDefaultConstraintViolation(); // 禁用默認(rèn)的 message 的值
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()
.replaceAll("\\{value}", values.toString())).addConstraintViolation(); // 重新添加錯誤提示語句
return false;
}
}
validator 使用參考:
01.spring-mvc 結(jié)合 Java Validation Api 提升web開發(fā)效能