java使用validator进行校验
不管是html页面表单提交的对象数据还是和第三方公司进行接口对接,都需要对接收到的数据进行校验(非空、长度、格式等等)。如果使用if一个个进行校验(字段非常多),这是让人崩溃的过程。幸好jdk或hibernate都提供了对object对象的校验,只需加上相应的注解即可。
本人喜欢学习时,都建立个maven小项目进行实践学习。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fei</groupId> <artifactId>validation-test</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>2.2.4</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> </dependencies> </project>是用来练手的
StudentInfo.java
package com.fei.info; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.NotBlank; public class StudentInfo { @NotBlank(message="用户名不能为空") private String userName; @NotBlank(message="年龄不能为空") @Pattern(regexp="^[0-9]{1,2}$",message="年龄是整数") private String age; /** * 如果是空,则不校验,如果不为空,则校验 */ @Pattern(regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$",message="出生日期格式不正确") private String birthday; @NotBlank(message="学校不能为空") private String school; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } }ValidatorUtil.java
package com.fei.util; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.groups.Default; public class ValidatorUtil { private static Validator validator = Validation.buildDefaultValidatorFactory() .getValidator(); public static <T> Map<String,StringBuffer> validate(T obj){ Map<String,StringBuffer> errorMap = null; Set<ConstraintViolation<T>> set = validator.validate(obj,Default.class); if(set != null && set.size() >0 ){ errorMap = new HashMap<String,StringBuffer>(); String property = null; for(ConstraintViolation<T> cv : set){ //这里循环获取错误信息,可以自定义格式 property = cv.getPropertyPath().toString(); if(errorMap.get(property) != null){ errorMap.get(property).append("," + cv.getMessage()); }else{ StringBuffer sb = new StringBuffer(); sb.append(cv.getMessage()); errorMap.put(property, sb); } } } return errorMap; } }ValidatorTest.java
package com.fei; import java.util.Map; import com.fei.info.StudentInfo; import com.fei.util.ValidatorUtil; public class ValidatorTest { public static void main(String[] args) { StudentInfo s = new StudentInfo(); long startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); s.setUserName("小明"); s.setAge("a10"); s.setBirthday("2016-9-1"); startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); } private static void print(Map<String,StringBuffer> errorMap){ if(errorMap != null){ for(Map.Entry<String, StringBuffer> m : errorMap.entrySet()){ System.out.println(m.getKey() + ":" + m.getValue().toString()); } } } }
来看看运行结果:
十二月 12, 2016 4:02:00 下午 org.hibernate.validator.internal.util.Version <clinit> INFO: HV000001: Hibernate Validator 5.1.3.Final school:学校不能为空 age:年龄不能为空 userName:用户名不能为空 ===============耗时(毫秒)=280 birthday:出生日期格式不正确 school:学校不能为空 age:年龄是整数 ===============耗时(毫秒)=3看到运行结果,心中一喜,达到了我们的要求。
看StudentInfo中的import发现注解的来源有来自javax和hibernate。
javax中有
hibernate中有
如果现有的校验规则都不满足,则可以自定义校验规则
Money.java
package com.fei.validator; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=MoneyValidator.class) public @interface Money { String message() default"不是金额形式"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
MoneyValidator.java
package com.fei.validator; import java.util.regex.Pattern; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class MoneyValidator implements ConstraintValidator<Money, Double> { private String moneyReg = "^\d+(\.\d{1,2})?$";//表示金额的正则表达式 private Pattern moneyPattern = Pattern.compile(moneyReg); public void initialize(Money money) { // TODO Auto-generated method stub } public boolean isValid(Double value, ConstraintValidatorContext arg1) { if (value == null) //金额是空的,返回true,是因为如果null,则会有@NotNull进行提示 //如果这里false的话,那金额是null,@Money中的message也会进行提示 //自己可以尝试 return true; return moneyPattern.matcher(value.toString()).matches(); } }
StudentInfo.java
加上,注意因为money是Double,所以不能用@NotBlank,因为@NotBlank是对字符串校验的
@NotNull(message="金额不能为空") @Money(message="金额格式不正确") private Double money;
ValidatorTest.java
package com.fei; import java.util.Map; import com.fei.info.StudentInfo; import com.fei.util.ValidatorUtil; public class ValidatorTest { public static void main(String[] args) { StudentInfo s = new StudentInfo(); long startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); s.setUserName("小明"); s.setAge("a10"); s.setBirthday("2016-9-1"); s.setMoney(100.00001); startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); } private static void print(Map<String,StringBuffer> errorMap){ if(errorMap != null){ for(Map.Entry<String, StringBuffer> m : errorMap.entrySet()){ System.out.println(m.getKey() + ":" + m.getValue().toString()); } } } }运行结果:
十二月 12, 2016 4:42:41 下午 org.hibernate.validator.internal.util.Version <clinit> INFO: HV000001: Hibernate Validator 5.1.3.Final school:学校不能为空 age:年龄不能为空 money:金额不能为空 userName:用户名不能为空 ===============耗时(毫秒)=280 birthday:出生日期格式不正确 school:学校不能为空 age:年龄是整数 money:金额格式不正确 ===============耗时(毫秒)=4
当然,如果你的项目使用springMVC或structs2,都会对应的集成方法。
如果校验的对象中包含另一个对象信息时,校验也要同时校验另一个对象,则可以使用@Valid
ParentInfo.java
package com.fei.info; import org.hibernate.validator.constraints.NotBlank; public class ParentInfo { @NotBlank(message="父亲名称不能为空") private String fatherName; @NotBlank(message="母亲名称不能为空") private String motherName; public String getFatherName() { return fatherName; } public void setFatherName(String fatherName) { this.fatherName = fatherName; } public String getMotherName() { return motherName; } public void setMotherName(String motherName) { this.motherName = motherName; } }StudentInfo.java
中加入,set,get是必须的
/** * 如果不加@NotNull,则prentInfo=null时,不会对ParentInfo内的字段进行校验 */ @NotNull(message="父母信息不能为空") @Valid private ParentInfo parentInfo;ValidatorTest.java
package com.fei; import java.util.Map; import com.fei.info.ParentInfo; import com.fei.info.StudentInfo; import com.fei.util.ValidatorUtil; public class ValidatorTest { public static void main(String[] args) { StudentInfo s = new StudentInfo(); long startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); s.setUserName("小明"); s.setAge("a10"); s.setBirthday("2016-9-1"); s.setMoney(100.00001); s.setParentInfo(new ParentInfo()); startTime = System.currentTimeMillis(); print(ValidatorUtil.validate(s)); System.out.println("===============耗时(毫秒)=" + (System.currentTimeMillis() - startTime)); } private static void print(Map<String,StringBuffer> errorMap){ if(errorMap != null){ for(Map.Entry<String, StringBuffer> m : errorMap.entrySet()){ System.out.println(m.getKey() + ":" + m.getValue().toString()); } } } }
运行结果:
十二月 12, 2016 4:56:16 下午 org.hibernate.validator.internal.util.Version <clinit> INFO: HV000001: Hibernate Validator 5.1.3.Final parentInfo:父母信息不能为空 school:学校不能为空 age:年龄不能为空 money:金额不能为空 userName:用户名不能为空 ===============耗时(毫秒)=285 birthday:出生日期格式不正确 school:学校不能为空 parentInfo.fatherName:父亲名称不能为空 age:年龄是整数 parentInfo.motherName:母亲名称不能为空 money:金额格式不正确 ===============耗时(毫秒)=9
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。