JSR规范
JSR是Java Specification Requests的缩写,意思是Java规范提案。是指向JCP(Java Community Process,JCP维护的规范包括J2ME、J2SE、J2EE,XML,OSS,JAIN等)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
JSR规范,JDBC、EJB、NIO、JDBC、JSP、JMX等都是JSR规范中的。
validation-api和hibernate-validator
validation-api只是一套标准,是Java EE6中的一项子规范,JSR规范编号303,叫做BeanValidation,官方参考实现是hibernate-validator。后来又扩展了JSR 349,提出了依赖注入、注解等内容。
hibernate-validator java代码
maven坐标
hibernate-validator中包含了validation-api,所以不用重复引入。
<!--注解实现校验-->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<!-- hibernate-validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.2.Final</version>
</dependency>
实体类
package com.validation;
import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class Student implements Serializable {
@NotNull(message = "名字不能为空")
private String name;
@Size(min = 6,max = 30,message = "地址应该在6-30字符之间")
private String address;
@DecimalMax(value = "100.00",message = "体重有些超标哦")
@DecimalMin(value = "60.00",message = "多吃点饭吧")
private BigDecimal weight;
private String friendName;
@AssertTrue
private Boolean isHaveFriend(){
return friendName != null?true:false;
}
@Future(message = "生日必须在当前时间之前")
private Date birthday;
@Pattern(regexp = "^(.+)@(.+)$",message = "邮箱的格式不合法")
private String email;
}
测试类
package com.validation;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
public class StudentTest implements Serializable {
//获取验证器工厂
private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
public static void main(String[] args) {
Student bean = new Student();
bean.setName(null);
bean.setAddress("扬州");
bean.setBirthday(new Date());
bean.setFriendName(null);
bean.setWeight(new BigDecimal(30));
bean.setEmail("163.com");
//验证实体数据
List<String> validate = validate(bean);
validate.forEach(row -> {
System.out.println(row.toString());
});
}
/**
* 验证实体
* @param t 实体类
* @return 返回实体类的验证message集合
*/
public static <T> List<String> validate(T t) {
Validator validator = factory.getValidator();
Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
List<String> messageList = new ArrayList<>();
for (ConstraintViolation<T> constraintViolation : constraintViolations) {
messageList.add(constraintViolation.getMessage());
}
return messageList;
}
}
测试结果
Spring MVC集成hibernate-validator
maven坐标
jsr-349,hibernate-validator中包含了validation-api 1.1.0这个接口包,所以不用重复引入。
<!--注解实现校验,spring mvc可以不引用,但是为了junit使用依然引用-->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<!-- hibernate-validator-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.2.Final</version>
</dependency>
spring-mvc.xml
HibernateValidator没有使用国际化,配置如下
<!-- HibernateValidator -->
<mvc:annotation-driven validator="validator"/>
<!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
model类
使用javax.validation的@NotNull、@Pattern、@Size和hibernate.validator的@NotEmpty、@Length等注解,注解中可以用message属性自定义提示。
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
@Data
@TableName(value = "t_admin")
public class TAdmin implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
@NotNull(message = "主键不能为null")
private Integer id;
@TableField(value = "name")
@NotEmpty
@Length(min = 5, max = 20)
@Pattern(regexp = "[a-zA-Z]{5,20}",message = "只能为5到20位的英文字母")
private String name;
@TableField(value = "username")
@NotEmpty
@Size(min = 5, max = 20)
private String username;
@TableField(value = "password")
@NotNull
private String password;
}
Controller层
@Valid或者@Validated注解验证。
@RequestMapping("/save")
@ResponseBody
public Object save(@Valid TAdmin user, BindingResult bindingResult) {
Map<String, Object> result = new HashMap<String, Object>();
/*获取BeanValid验证消息*/
if(bindingResult.hasErrors()) { //如果有验证出错误
if(bindingResult.hasErrors()) {
//获取所有错误
List<FieldError> errs = bindingResult.getFieldErrors();
//把所有所处的field和defaultmessage拿出来放入Map中
Map<String, String> mapErrors = new LinkedHashMap<String, String>();
for(FieldError err : errs) {
mapErrors.put(err.getField(), err.getDefaultMessage());
}
result.put("success", false);
result.put("errors", mapErrors);
return result;
}
}
boolean r = adminService.save(user);
result.put("success", true);
result.put("result", r);
return result;
}