數據驗證器
阿新 • • 發佈:2018-07-25
field pty email enc charat val 年齡 convert 實體
依賴
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.11.Final</version> </dependency>
驗證器相關類
/** * 驗證器接口 */ public interface Validator { /** * POJO實體驗證 * @param entity * @param <T> * @return */ <T> List<ValidateResult> validateEntity(T entity); /** * 方法參數驗證 * @param obj * @param method * @param params * @param <T> * @return */ <T> List<ValidateResult> validateMethodParams(T obj, Method method, Object[] params); } /** * 默認驗證.javax.validation */ public class DefaultValidator implements Validator { private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); private final ExecutableValidator executableValidator = factory.getValidator().forExecutables(); private final javax.validation.Validator validator = factory.getValidator(); @Override public <T> List<ValidateResult> validateEntity(T entity) { Set<ConstraintViolation<T>> violationSet = validator.validate(entity); return convert(violationSet); } @Override public <T> List<ValidateResult> validateMethodParams(T obj, Method method, Object[] params) { Set<ConstraintViolation<T>> violationSet = executableValidator.validateParameters(obj, method, params); return convert(violationSet); } protected <T> List<ValidateResult> convert(Set<ConstraintViolation<T>> violationSet){ if (violationSet == null || violationSet.isEmpty()) return null; List<ValidateResult> resultList = new ArrayList<>(violationSet.size()); for (ConstraintViolation cv : violationSet){ String name = cv.getPropertyPath().toString(); resultList.add(new ValidateResult(name, cv.getMessage(), cv.getInvalidValue())); } return resultList; } } /** * 驗證的結果 */ public class ValidateResult { /** * 驗證的字段名稱 */ private String name; /** * 提示信息 */ private String msg; /** * 驗證的值 */ private Object validatedVal; public ValidateResult(String name, String msg, Object validatedVal) { this.name = name; this.msg = msg; this.validatedVal = validatedVal; } @Override public String toString() { return "ValidateResult{" + "name='" + name + '\'' + ", msg='" + msg + '\'' + ", validatedVal=" + validatedVal + '}'; } }
自定義驗證器
import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; /** * 自定義×××號碼驗證註解 */ @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Repeatable(IDCardNumber.List.class) @Documented @Constraint(validatedBy = {IDCardNumberValidator.class}) public @interface IDCardNumber { String message() default "invalid IDCardNumber"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @Documented @interface List { IDCardNumber[] value(); } } /** * IDCardNumber驗證器 */ public class IDCardNumberValidator implements ConstraintValidator<IDCardNumber, String> { @Override public void initialize(IDCardNumber constraintAnnotation) { } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (null == value || "".equals(value)) return false; if (value.length() != 18) return false; if (getValidateCode(value) != value.toUpperCase().charAt(17)) return false; return true; } /** * 十七位數字本體碼權重 */ private static final int[] weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; /** * mod11,對應校驗碼字符值 */ private static final char[] validate = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; public char getValidateCode(String id17) { int sum = 0; int mode = 0; for (int i = 0; i < 17; i++) { //sum = sum + Integer.parseInt(String.valueOf(id17.charAt(i))) * weight[i]; sum = sum + (id17.charAt(i) - 48) * weight[i]; } mode = sum % 11; return validate[mode]; } }
測試
@Valid public class User { @NotNull(message = "id不能為空") private Integer id; private String name; @NotNull(message = "郵箱不能為空") @Email(message = "不合法的郵箱") private String email; @IDCardNumber(message = "無效×××") private String IDCardNumber; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getIDCardNumber() { return IDCardNumber; } public void setIDCardNumber(String IDCardNumber) { this.IDCardNumber = IDCardNumber; } public void setField(@NotNull(message = "姓名不能為空") String name, @Range(min = 18, max = 60, message = "年齡只能在18至69歲") int age){} } public class Test { public static void main(String[] args) throws NoSuchMethodException { DefaultValidator defaultValidator = new DefaultValidator(); User user = new User(); user.setEmail("23424"); user.setIDCardNumber("23424"); List<ValidateResult> resultList = defaultValidator.validateEntity(user); System.out.println(resultList.toString()); List<ValidateResult> validateResults = defaultValidator.validateMethodParams(user, user.getClass().getMethod("setField", String.class, int.class), new Object[]{null, 10}); System.out.println(validateResults.toString()); } }
輸出結果
[ValidateResult{name='id', msg='id不能為空', validatedVal=null}, ValidateResult{name='IDCardNumber', msg='無效×××', validatedVal=23424}, ValidateResult{name='email', msg='不合法的郵箱', validatedVal=23424}] [ValidateResult{name='setField.arg1', msg='年齡只能在18至69歲', validatedVal=10}, ValidateResult{name='setField.arg0', msg='姓名不能為空', validatedVal=null}]
數據驗證器