一、前言
在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节。比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间、成本、质量的博弈中必然会落后。所以把校验层抽象出来是必然的结果,下面说下几种解决方案。
二、解决方案
1、struts2的valid 可以通过配置xml,xml中描述规则和返回的信息,这种方式比较麻烦、开发效率低,不推荐
2、validation bean 是基于JSR-303标准开发出来的,使用注解方式实现,及其方便,下面会重点介绍
3、Hibernate Validator.这是一个hibernate独立的包,可以直接引用,实际上是在validation bean基础上进行了扩展,如下图
4、oval 是一个可扩展的Java对象数据验证框架,验证的规则可以通过配置文件、Annotation、POJOs 进行设定。可以使用纯 Java 语言、JavaScript 、Groovy 、BeanShell 等进行规则的编写
三、bean validation 框架验证介绍
bean validation 包放在maven上维护,最新包的坐标如下:
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency>
最新的地址:http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22javax.validation%22%20AND%20a%3A%22validation-api%22
下载之后打开这个包,有个package叫constraints,里面放的就是验证的的注解:
下面开始用代码实践一下:
1、定义一个待验证的bean:Student.java
1 package com.use; 2 3 import javax.validation.constraints.*; 4 import java.io.Serializable; 5 import java.math.BigDecimal; 6 import java.util.Date; 7 8 public class Student implements Serializable { 9 10 11 @NotNull(message = "名字不能为空") 12 private String name; 13 14 @Size(min = 6,max = 30,message = "地址应该在6-30字符之间") 15 private String address; 16 17 @DecimalMax(value = "100.00",message = "体重有些超标哦") 18 @DecimalMin(value = "60.00",message = "多吃点饭吧") 19 private BigDecimal weight; 20 21 private String friendName; 22 @AssertTrue 23 private Boolean isHaveFriend(){ 24 return friendName != null?true:false; 25 } 26 27 @Future(message = "生日必须在当前实践之前") 28 private Date birthday; 29 30 @Pattern(regexp = "^(.+)@(.+)$",message = "邮箱的格式不合法") 31 private String email; 32 33 34 public String getName() { 35 return name; 36 } 37 38 public void setName(String name) { 39 this.name = name; 40 } 41 42 public String getAddress() { 43 return address; 44 } 45 46 public void setAddress(String address) { 47 this.address = address; 48 } 49 50 public BigDecimal getWeight() { 51 return weight; 52 } 53 54 public void setWeight(BigDecimal weight) { 55 this.weight = weight; 56 } 57 58 public String getFriendName() { 59 return friendName; 60 } 61 62 public void setFriendName(String friendName) { 63 this.friendName = friendName; 64 } 65 66 public Date getBirthday() { 67 return birthday; 68 } 69 70 public void setBirthday(Date birthday) { 71 this.birthday = birthday; 72 } 73 74 public String getEmail() { 75 return email; 76 } 77 78 public void setEmail(String email) { 79 this.email = email; 80 } 81 }
2、测试类:StudentTest.java
1 package com.use; 2 3 import javax.validation.ConstraintViolation; 4 import javax.validation.Validation; 5 import javax.validation.Validator; 6 import javax.validation.ValidatorFactory; 7 import java.io.Serializable; 8 import java.math.BigDecimal; 9 import java.util.ArrayList; 10 import java.util.Date; 11 import java.util.List; 12 import java.util.Set; 13 14 public class StudentTest implements Serializable { 15 public static void main(String[] args) { 16 Student xiaoming = getBean(); 17 List<String> validate = validate(xiaoming); 18 validate.forEach(row -> { 19 System.out.println(row.toString()); 20 }); 21 22 } 23 24 private static Student getBean() { 25 Student bean = new Student(); 26 bean.setName(null); 27 bean.setAddress("北京"); 28 bean.setBirthday(new Date()); 29 bean.setFriendName(null); 30 bean.setWeight(new BigDecimal(30)); 31 bean.setEmail("xiaogangfan163.com"); 32 return bean; 33 } 34 35 private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 36 37 public static <T> List<String> validate(T t) { 38 Validator validator = factory.getValidator(); 39 Set<ConstraintViolation<T>> constraintViolations = validator.validate(t); 40 41 List<String> messageList = new ArrayList<>(); 42 for (ConstraintViolation<T> constraintViolation : constraintViolations) { 43 messageList.add(constraintViolation.getMessage()); 44 } 45 return messageList; 46 } 47 }
3、总结
- 像@NotNull、@Size等比较简单也易于理解,不多说
- @Pattern 因为这个是正则,所以能做的事情比较多,比如中文还是数字、邮箱、长度等等都可以做
- @AssertTRue 这个与其他的校验注解有着本质的区别,因为与别的字段发生了关联。例子中isHaveFriend方法依赖friendName字段校验
- 验证的api是经过我加工了一下,这样可以批量返回校验的信息
- 这个框架还是比较简单的,有时我们需要的注解可能没有提供,这时候就需要自定义注解,字节写实现了。下一节会讨论下hibernate validation,
时间: 2024-08-06 05:03:05