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;
}

