菜鳥的Hibernate Validator實戰教程
說明
更新時間:2020/5/28 12:11,更新了list分組校驗以及常用註解
更新時間:2020/5/27 23:23,更新了Hibernate Validator基本使用
本文主要記錄本人在學習Hibernate Validator時的一些知識點,以便日後查看,本文會持續更新,不斷地擴充
本文僅爲記錄學習軌跡,如有侵權,聯繫刪除
一、Hibernate Validator簡介
Hibernate Validator的出現是爲了解決平時的項目開發中的數據正確性的校驗問題,在平時開發中,爲了確保數據的正確性,經常需要做數據的校驗,傳統的數據校驗會顯得代碼冗長,而且不美觀,而且如果項目較大的話,會出現很多重複代碼。爲了解決這個問題,Java中提供了Bean Validation的標準,該標準規定了校驗的具體內容,通過簡單的註解就能完成必要的校驗邏輯了,相對來說就方便了很多,而該規範其實只是規範,並沒有具體的實現,Hibernate提供了具體的實現,也即Hibernate Validator,這個也是目前使用得比較多的驗證器了。
二、快速入門
入門案例
實體類
package com.zsc.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Father {
@Null(message = "主鍵不可以有值")
private Integer id;
@NotBlank(message = "名字不能爲空")
private String name;
@NotNull(message = "年齡不能爲空")
private Integer age;
}
Controller
package com.zsc.controller;
import com.zsc.po.Father;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
@Controller
public class FatherController {
@RequestMapping("/father")
public void father(@RequestBody @Valid Father father, BindingResult result){
//處理業務邏輯
if(result.hasErrors()){
for (ObjectError error : result.getAllErrors()) {
System.out.println(error.getDefaultMessage());
}
}
}
}
用Postman發起請求
控制檯輸出
可以看到後臺確實有進行驗證,同時也捕捉到了相應的異常,所以控制檯會報錯,然而將這些異常直接返回給前端是不行的,而且這裏控制檯還報錯了就更別說了,所以,下面會對這些數據驗證後產生的異常進行處理。
三、全局異常處理
在進行數據驗證後,產生的異常需要經過處理後才能返回給前端
首先需要一個類(ResultVo),記錄後端處理後的結果返回
package com.zsc.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.zsc.enums.ErrorCode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)//不爲空的項纔會加入序列化,表現爲返回的信息中只返回不爲null參數
public class ResultVo {
/**
* 後端是否處理成功
*/
private boolean success;
/**
* 返回狀態碼
*/
private String code;
/**
* 返回的處理後的信息
*/
private String msg;
/**
* 給前端的返回值
*/
private Object data;
/**
* 成功的返回
* @return
*/
public static ResultVo success(){
ResultVo resultVo = new ResultVo();
resultVo.setSuccess(true);
return resultVo;
}
/**
* 成功的返回
* @param data
* @return
*/
public static ResultVo success(Object data){
ResultVo resultVo = new ResultVo();
resultVo.setSuccess(true);
resultVo.setData(data);
return resultVo;
}
/**
* 失敗的返回
* @param errorCode
* @return
*/
public static ResultVo fail(ErrorCode errorCode){
ResultVo resultVo = new ResultVo();
resultVo.setSuccess(false);
resultVo.setCode(errorCode.getCode());
resultVo.setMsg(errorCode.getMsg());
return resultVo;
}
/**
* 失敗的返回
* @param errorCode
* @param data
* @return
*/
public static ResultVo fail(ErrorCode errorCode,Object data){
ResultVo resultVo = new ResultVo();
resultVo.setSuccess(false);
resultVo.setCode(errorCode.getCode());
resultVo.setMsg(errorCode.getMsg());
resultVo.setData(data);
return resultVo;
}
}
後端處理後,將結果通過ResultVo 類返回給前端,返回的時候需要設置錯誤狀態碼,錯誤信息等,爲了方便查看狀態碼和狀態碼對應的錯誤信息,這裏需要建一個枚舉類(ErrorCode)存放這些狀態碼和狀態碼對應的錯誤信息
package com.zsc.enums;
public enum ErrorCode {
//這裏簡單的將參數狀態碼‘1000’錯誤信息設置爲‘參數不正確’
PARAM_ERROR("1000","參數不正確");
//這裏還可以設置其他狀態碼和對應的錯誤信息
private String code;
private String msg;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public void setCode(String code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
ErrorCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
}
現在需要創建一個類(CtrlAdvice )用來捕捉上面數據驗證後的處理
package com.zsc.config;
import com.zsc.enums.ErrorCode;
import com.zsc.vo.ResultVo;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
import java.util.stream.Collectors;
@ControllerAdvice(basePackages = "com.zsc.controller")//配置要捕捉的異常的包
@ResponseBody
public class CtrlAdvice {
//捕捉到異常後跳轉到該方法
@ExceptionHandler
public ResultVo exceptionHandler(MethodArgumentNotValidException e){
/**
* MethodArgumentNotValidException:捕捉前端傳上來的參數異常
* id - 主鍵不可以有值
* name - 名字不能爲空
* birthday - 出生日期不能爲空
* age - 年齡不能爲空
* email - 郵件格式不正確
*/
/**
* 將異常的id(FieldError::getField)和值(getDefaultMessage)封裝成一個map,返回給ResultVo
*/
Map<String, String> collect = e.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
return ResultVo.fail(ErrorCode.PARAM_ERROR,collect);
}
}
配置好之後就可以進行真正的數據驗證了
四、數據驗證
控制層的校驗
做完全局異常處理後,下面就可以進行真正的數據驗證了,數據驗證除了對基本數據類型的驗證之外,還包括級聯驗證,即在一個類中存在自定義的數據類型,有一對一,一對多的情況,下面給出數據驗證例子。
實體類User
package com.zsc.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Null(message = "主鍵不可以有值")
private Integer id;
@NotBlank(message = "名字不能爲空")
private String name;
@NotNull(message = "出生日期不能爲空")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
@NotNull(message = "年齡不能爲空")
private Integer age;
@NotBlank(message = "郵件不能爲空")
@Email(message = "郵件格式不正確")
private String email;
//驗證自定義實體類:一對一
@Valid
private Father father;
//驗證自定義實體類列表:一對多
private List<@Valid Son> sons;
}
實體類Father
package com.zsc.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Father {
@Null(message = "主鍵不可以有值")
private Integer id;
@NotBlank(message = "名字不能爲空")
private String name;
@NotNull(message = "年齡不能爲空")
private Integer age;
}
實體類Son
package com.zsc.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Son {
@Null(message = "主鍵不可以有值")
private Integer id;
@NotBlank(message = "名字不能爲空")
private String name;
@NotNull(message = "年齡不能爲空")
private Integer age;
}
控制器UserController
package com.zsc.controller;
import com.zsc.po.User;
import com.zsc.vo.ResultVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@Validated//對本類中的方法開啓參數驗證功能
public class UserController {
@RequestMapping("/user")
public ResultVo user(@RequestBody @Valid User user){
//處理業務邏輯
return ResultVo.success();
}
}
下面進行測試
服務層的校驗
服務層的校驗,校驗產生的異常就不是MethodArgumentNotValidException異常了,而是ConstraintViolationException異常,所以之前配置的異常捕捉就不會捕捉到ConstraintViolationException異常,需要在全局配置類CtrlAdvice 裏面配置捕捉ConstraintViolationException的異常並做相應處理。
CtrlAdvice中新增服務層的異常捕捉
package com.zsc.config;
import com.zsc.enums.ErrorCode;
import com.zsc.vo.ResultVo;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.Map;
import java.util.stream.Collectors;
@ControllerAdvice(basePackages = "com.zsc.controller")//配置要捕捉的異常的包
@ResponseBody
public class CtrlAdvice {
//對應控制層的數據驗證
//捕捉到MethodArgumentNotValidException異常後跳轉到該方法
@ExceptionHandler
public ResultVo exceptionHandler(MethodArgumentNotValidException e){
/**
* MethodArgumentNotValidException:捕捉前端傳上來的參數異常
* id - 主鍵不可以有值
* name - 名字不能爲空
* birthday - 出生日期不能爲空
* age - 年齡不能爲空
* email - 郵件格式不正確
*/
/**
* 將異常的id(FieldError::getField)和值(getDefaultMessage)封裝成一個map,返回給ResultVo
*/
Map<String, String> collect = e.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
return ResultVo.fail(ErrorCode.PARAM_ERROR,collect);
}
//對應服務層的校驗
//捕捉到ConstraintViolationException異常後跳轉到該方法
@ExceptionHandler
public ResultVo exceptionHandler(ConstraintViolationException e){
Map<Path, String> collect = e.getConstraintViolations().stream()
.collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage));
return ResultVo.fail(ErrorCode.PARAM_ERROR,collect);
}
}
配置好服務層的異常捕捉後,設置服務層要校驗的方法
服務層接口:UserService
package com.zsc.service;
import com.zsc.po.User;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
public interface UserService {
void add(@Valid User user);//服務層的數據校驗
//數據校驗還可以這樣校驗
@NotNull User getById(@NotNull Integer id);
}
服務層接口實現類UserServiceImpl
package com.zsc.service.impl;
import com.zsc.po.User;
import com.zsc.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
@Service
@Validated
public class UserServiceImpl implements UserService {
@Override
public void add(@Valid User user) {
//業務邏輯
System.out.println("數據添加成功");
}
@Override
public @NotNull User getById(@NotNull Integer id) {
return null;
}
}
控制層新增userService方法
package com.zsc.controller;
import com.zsc.po.User;
import com.zsc.service.UserService;
import com.zsc.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@Validated//對本類中的方法開啓參數驗證功能
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/user")
public ResultVo user(@RequestBody @Valid User user){
//處理業務邏輯
return ResultVo.success();
}
@RequestMapping("/userService")
public ResultVo userService(@RequestBody User user){
//處理業務邏輯
userService.add(user);
return ResultVo.success();
}
}
測試結果
分組校驗
設想一下,User的主鍵id由於在進行數據的插入時,主鍵id一般由數據庫默認自增,所以在前端發起插入數據時不需要傳入id,所以上面圖的id做了@Null驗證,但是如果時數據更新的話,User的id就需要傳給後端,但上面圖的id卻做了@Null驗證,爲了解決這個矛盾,就需要做分組校驗,新修改的User如下圖所示
實體類User
package com.zsc.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
//分組校驗:Update驗證組和Add驗證組
public interface Update{}
public interface Add{}
/**
* 如果指定了驗證組,那麼該參數就只屬於指定的驗證組
*
* 如果沒有指定校驗組,那麼該參數就只屬於默認組
*/
@Null(message = "插入數據時主鍵不可以有值",groups = {Add.class})
@NotNull(message ="更新時需要傳主鍵id過來",groups = {Update.class})
private Integer id;
@NotBlank(message = "名字不能爲空")
private String name;
@NotNull(message = "出生日期不能爲空")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
@NotNull(message = "年齡不能爲空")
private Integer age;
@NotBlank(message = "郵件不能爲空")
@Email(message = "郵件格式不正確")
private String email;
//驗證自定義實體類:一對一
@Valid
private Father father;
//驗證自定義實體類列表:一對多
private List<@Valid Son> sons;
}
控制層
package com.zsc.controller;
import com.zsc.po.User;
import com.zsc.service.UserService;
import com.zsc.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.groups.Default;
@RestController
@Validated//對本類中的方法開啓參數驗證功能
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/addUser")
public ResultVo add(@RequestBody @Validated({User.Add.class, Default.class}) User user) {
//增加用戶時,數據校驗就採用Add驗證組和默認驗證組
//處理業務邏輯
return ResultVo.success();
}
@RequestMapping("/updateUser")
public ResultVo update(@RequestBody @Validated({User.Update.class, Default.class}) User user) {
//更新用戶時,數據校驗就採用Update驗證組和默認驗證組
//處理業務邏輯
return ResultVo.success();
}
@RequestMapping("/userService")
public ResultVo userService(@RequestBody User user) {
//處理業務邏輯
userService.add(user);
return ResultVo.success();
}
}
測試插入數據(此時主鍵id校驗不能有值)
測試更新數據(此時主鍵id需要傳值過來)
自定義註解校驗
一般Validator自帶的註解校驗足夠應對正常的數據校驗,但如果沒有我們想要的數校驗方式,可以自己定義一個註解進行自定義註解校驗,假設現在要校驗一個字段,如果該字段是Integer則要求該參數必須是偶數,如果是List則要求該參數的列表的個數(list.size()必須是偶數,可以自定義該註解。
在新建的包validator下的新建註解Even
package com.zsc.validator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 自定義註解校驗
* 檢驗Integer字段是否爲偶數
*/
@Documented//生成文檔
@Target({ElementType.FIELD})//表示該註解作用於字段
@Retention(RetentionPolicy.RUNTIME)//表示在運行是依然生效
@Constraint(
validatedBy = {EvenForInteger.class,EvenForList.class}//添加實現類
)
public @interface Even {
String message() default "必須是偶數";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
註解對應的實現類EvenForInteger
package com.zsc.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class EvenForInteger implements ConstraintValidator<Even,Integer> {//表示作用於註解Even,要驗證的類型爲Integer
@Override
public void initialize(Even constraintAnnotation) {
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
//編寫驗證的邏輯
if(value == null){//如果null直接驗證成功,null交給NotNull註解去驗證
return true;
}
return value%2==0;
}
}
註解對應的實現類EvenForList
package com.zsc.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
public class EvenForList implements ConstraintValidator<Even, List> {//表示作用於註解Even,要驗證的類型爲List
@Override
public void initialize(Even constraintAnnotation) {
}
@Override
public boolean isValid(List value, ConstraintValidatorContext context) {
//編寫驗證的邏輯
if(value == null){//如果null直接驗證成功,null交給NotNull註解去驗證
return true;
}
return value.size() %2==0;//表示要驗證的list的列表個數爲偶數
}
}
做完就可以開始測試,這裏在Father類上增加了兩個字段用於測試註解Even
list中的分組校驗
假設有一種場景如下
爲此,需要定義一個註解用來校驗上面的場景
自定義註解ValidList
package com.zsc.validation;
import com.zsc.validation.validator.ValidListValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.groups.Default;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 支持 list 中的分組校驗
*/
@Target({FIELD,PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ValidListValidator.class})
public @interface ValidList {
/**
* 要驗證的分組
*/
Class<?>[] groupings() default {Default.class};
boolean quickFail() default false;//快速失敗模式,一旦有校驗失敗的情況就不會再往下校驗
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
對應的實現類ValidListValidator
package com.zsc.validation.validator;
import com.zsc.config.ListValidException;
import com.zsc.utils.ValidatorUtils;
import com.zsc.validation.ValidList;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class ValidListValidator implements ConstraintValidator<ValidList, List> {
Class<?>[] groupings;
boolean quickFail;
@Override
public void initialize(ValidList validList) {
groupings = validList.groupings();
quickFail = validList.quickFail();
}
@Override
public boolean isValid(List list, ConstraintValidatorContext context) {
Map<Integer, Set<ConstraintViolation<Object>>> errors = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
Set<ConstraintViolation<Object>> error = ValidatorUtils.validator.validate(object, groupings);
if (error.size()>0) {
errors.put(i, error);
if (quickFail){
throw new ListValidException(errors);
}
}
}
if (errors.size()>0){
throw new ListValidException(errors);
}
return true;
}
}
因爲需要用到底層的validator,所以需要寫一個工具類ValidatorUtils將validator注入進來
package com.zsc.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.validation.Validator;
@Component
public class ValidatorUtils {
public static Validator validator;
@Autowired
public void setValidator(Validator validator) {
ValidatorUtils.validator = validator;
}
}
全局異常處理,需要在CtrlAdvice 新增異常捕獲
package com.zsc.config;
import com.zsc.enums.ErrorCode;
import com.zsc.vo.ResultVo;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import javax.validation.ValidationException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@ControllerAdvice(basePackages = "com.zsc.controller")//配置要捕捉的異常的包
@ResponseBody
public class CtrlAdvice {
//對應控制層的數據驗證
//捕捉到MethodArgumentNotValidException異常後跳轉到該方法
@ExceptionHandler
public ResultVo exceptionHandler(MethodArgumentNotValidException e){
/**
* MethodArgumentNotValidException:捕捉前端傳上來的參數異常
* id - 主鍵不可以有值
* name - 名字不能爲空
* birthday - 出生日期不能爲空
* age - 年齡不能爲空
* email - 郵件格式不正確
*/
/**
* 將異常的id(FieldError::getField)和值(getDefaultMessage)封裝成一個map,返回給ResultVo
*/
Map<String, String> collect = e.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
return ResultVo.fail(ErrorCode.PARAM_ERROR,collect);
}
//對應服務層的校驗
//捕捉到ConstraintViolationException異常後跳轉到該方法
@ExceptionHandler
public ResultVo exceptionHandler(ConstraintViolationException e){
Map<Path, String> collect = e.getConstraintViolations().stream()
.collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage));
return ResultVo.fail(ErrorCode.PARAM_ERROR,collect);
}
@ExceptionHandler
public ResultVo exceptionHandler(ValidationException e){
Map<Integer, Map<Path, String>> map = new HashMap<>();
((ListValidException)e.getCause()).getErrors().forEach((integer, constraintViolations) -> {
map.put(integer, constraintViolations.stream()
.collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage)));
});
return ResultVo.fail(ErrorCode.PARAM_ERROR,map);
}
@ExceptionHandler
public ResultVo exceptionHandler(Exception e){
return ResultVo.fail(ErrorCode.SYSTEM_ERROR);
}
}
同時還需要一個異常類ListValidException
package com.zsc.config;
import javax.validation.ConstraintViolation;
import java.util.Map;
import java.util.Set;
public class ListValidException extends RuntimeException {
private Map<Integer, Set<ConstraintViolation<Object>>> errors;
public ListValidException(Map<Integer, Set<ConstraintViolation<Object>>> errors) {
this.errors = errors;
}
public Map<Integer, Set<ConstraintViolation<Object>>> getErrors() {
return errors;
}
public void setErrors(Map<Integer, Set<ConstraintViolation<Object>>> errors) {
this.errors = errors;
}
}
完成後開始進行測試,主要測試兩種模式,快速結束模式和非快速結束模式
五、常用註解
給出Hibernate Validator常用註解,下面會詳細講到這些註解
@AssertTrue | 用於boolean字段,該字段只能爲true |
@AssertFalse | 該字段的值只能爲false |
@CreditCardNumber | 對信用卡號進行一個大致的驗證 |
@DecimalMax | 只能小於或等於該值,字段或屬性. 支持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
@DecimalMin | 只能大於或等於該值,字段或屬性. 支持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
@Digits(integer=,fraction=) | 檢查是否是一種數字的整數、分數,小數位數的數字,支持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
檢查是否是一個有效的email地址,需要是String類型的. | |
@Future | 檢查該字段的日期是否是屬於將來的日期,支持類型是java.util.Date 和java.util.Calendar |
@Length(min=,max=) | 檢查所屬的字段的長度是否在min和max之間,只能用於字符串 |
@Max | 該字段的值只能小於或等於該值,持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
@Min | 該字段的值只能大於或等於該值,持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
@NotNull | 不能爲null,支持所有類型 |
@NotBlank | 不能爲空,檢查時會將空格忽略,一般用於String |
@NotEmpty | 不能爲空,這裏的空是指空字符串,支持的類型包括String, Collection, Map 和數組. |
@Null | 檢查該字段爲空 |
@Past | 檢查該字段的日期是在過去 |
@Pattern(regex=,flag=) | 被註釋的元素必須符合指定的正則表達式,必須是String類型 |
@Range(min=,max=,message=) | 被註釋的元素必須在合適的範圍內 |
@Size(min=, max=) | 檢查該字段的size是否在min和max之間,可以是字符串、數組、集合、Map等 |
@URL(protocol=,host,port) | 檢查是否是一個有效的URL,如果提供了protocol,host等,則該URL還需滿足提供的條件 |
@Valid | 該註解主要用於字段爲一個包含其他對象的集合或map或數組的字段,或該字段直接爲一個其他對象的引用,這樣在檢查當前對象的同時也會檢查該字段所引用的對象 |
@Range(min=,max=) | min <= 數字 <= max,段或屬性. 支持類型包括BigDecimal,BigInteger, String,byte, short, int, long和其各自對應的包裝器類型. |
舉例