一 前言
本篇是關於springboot的參數校驗知識,當然也適用其它java應用;讀完本篇將學會基本的參數校驗,自定義參數校驗和分組參數校驗;良好的代碼規范和書寫方式猶如散文版清麗脫俗,行雲流水;
公眾號:知識追尋者
知識追尋者(Inheriting the spirit of open source, Spreading technology knowledge;)
二 校驗入門
2.1 pom.xml
springboot在 web啟動器中已經包含validator包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
非springboot項目,需要自行引入依賴
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>3.0.3</version>
</dependency>
2.2 常用約束說明
@Null
: 元素為 null@NotNull
: 元素不為 null@AssertTrue
: 元素為 true@AssertFalse
: 元素為 false@Min(value)
: 數字的值大於等於指定的最小值@Max(value)
: 個數字的值小於等於指定的最大值@DecimalMin(value)
:大數值大於等於指定的最小值@DecimalMax(value)
: 大數值小於等於指定的最大值@Size(max=, min=)
: 元素的大小在指定的范圍內@Digits (integer, fraction)
: 元素是一個數字,其值必須在可接受的范圍內@Past
: 一個過去的日期@Future
: 一個將來的日期@Pattern(regex=,flag=)
:指定的正則表達式@URL
:必須是一個URL@Email
:必須是email格式@NotBlank
: 字符串不能為空@NotEmpty
:集合不能為空@Length
: 長度必須在指定范圍內@Valid
:對實體類進行校驗
2.4 實體約束示例
- 簡單注解約束使用示例如下;
- 如果成員是實體,需要帶上
@Valid
注解;
/**
* @Author lsc
* <p> </p>
*/
@Data
public class SysUser {
private Long id;
@NotNull(message ="用戶名不能為空")
@Size(min = 3, max = 5, message = "用戶名長度為{min}-{max}之間")
private String username;
@NotNull(message ="昵稱不能為空")
private String name;
@NotNull(message ="密碼不能為空")
private String password;
@Email(message = "郵箱格式不合法")
private String email;
private String gender;
}
2.5 控制層示例
- 需要在class加上
@Validated
; - 如果參數是實體 需要 加上
@Valid
注解
/**
* @Author lsc
* <p> </p>
*/
@RestController
@Validated
public class SysUserController {
// 方法參數為實體校驗
@PostMapping("/register")
public ResponseEntity register(@Valid @RequestBody SysUser sysUser){
return ResponseEntity.ok(sysUser);
}
// 方法參數校驗
@GetMapping("user")
public ResponseEntity getUser(@NotNull(message ="用戶名不能為空") String username) {
SysUser sysUser = new SysUser();
sysUser.setName("知識追尋者");
return ResponseEntity.ok(sysUser);
}
}
2.6 異常捕獲
全局異常捕獲,當出現參數校驗不合法時捕獲異常,並且返回給前端;
/**
* @Author lsc
* <p> </p>
*/
@ControllerAdvice
public class GlobHandler {
// 捕獲方法參數校驗異常
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResponseEntity constraintViolationExceptionHandler(ConstraintViolationException e){
Set<ConstraintViolation<?>> message = e.getConstraintViolations();
HashMap<String, Object> map = new HashMap<>();
message.stream().forEach(msg -> {
String path = msg.getPropertyPath().toString();
String field = path.substring(path.indexOf(".")+1);
map.put(field,msg.getMessageTemplate());
});
return ResponseEntity.ok(map);
}
// 捕獲實體參數校驗異常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity resolveMethodArgumentNotValidException(MethodArgumentNotValidException e){
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
HashMap<String, Object> map = new HashMap<>();
allErrors.stream().forEach(error -> {
FieldError fieldError = (FieldError) error;
map.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return ResponseEntity.ok(map);
}
}
2.7 請求示例
三 自定義校驗規則
特殊的字段需要自定義規則,比如身份證號碼,郵箱,電話等;
定義校驗注解
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = GenderValidator.class)
@Documented
public @interface Gender {
String message() default "性別為男或者女";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default {};
}
GenderValidator 實現 ConstraintValidator 接口並提供校驗規則
/**
* @Author lsc
* <p> </p>
*/
public class GenderValidator implements ConstraintValidator<Gender, String> {
// 初始化校驗值
@Override
public void initialize(Gender constraintAnnotation) {
}
// 校驗規則
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return "男".equals(value) || "女".equals(value);
}
}
在成員變量使用 注解
@Gender()
private String gender;
四 分組校驗
默認情況下,不指定分組都屬於默認組;使用分組校驗有利於分層校驗開發;
新建2個接口,一個用於查詢, 一個用於添加
/**
* @Author lsc
* <p> </p>
*/
public interface ADD extends Default {
}
public interface Select extends Default {
}
修改 實體校驗規則,如果不指定分組 默認是 Default 組;
@NotNull(message ="用戶名不能為空",groups = ADD.class)
@Size(min = 3, max = 5, message = "用戶名長度為{min}-{max}之間")
private String username;
@NotNull(message ="昵稱不能為空", groups = Select.class)
private String name;
@NotNull(message ="密碼不能為空",groups = ADD.class)
private String password;
@Email(message = "郵箱格式不合法", groups = Select.class)
private String email;
控制層示例,此時只會校驗 ADD 組和 Default組
// 分組校驗
@PostMapping("/user")
public ResponseEntity addUser(@Validated(value = ADD.class) @RequestBody SysUser sysUser){
return ResponseEntity.ok(sysUser);
}
五 參考文檔
https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/
https://zhuanlan.zhihu.com/p/96403211
https://blog.csdn.net/justry_deng/article/details/86571671
https://juejin.im/post/5dc8bc745188254e7a155ba0
https://www.jianshu.com/p/89a675b7c900
本套教程
- springboot入門 (1)
- Springboot自定義banner(2)
- springboot配置文件解析(3)
- springboot集成mybatis(4)
- springboot集成jdbcTemplate(5)
- spingboot單元測試(6)
- springboot集成thymeleaf(7)
- springboot多文件上傳(8)
- springboot文件下載(9)
- Springboot自定義異常類(10)
- springboot多環境配置(11)
- springboot自動配置原理解析(12)
- springboot集成restTemplate接口調用(13)
- springboot集成任務調度(14)
- springboot跨域CORS處理(15)
- springboot開啟GIZP壓縮(16)
- springboot集成logback(17)
- springboot集成Swagger(18)
- springboot集成actuator后台監控(19)
- springboot集成mybatis+oracle+druid(20)
- springboot 集成springsession(21)
- springboot集成jwt(22)
- springboot集成admin后台監控(23)
- springboot集成redis基礎篇(24)
- springboot集成redis緩存篇(25)
- springboot使用AOP日志攔截(26)
- springboot集成Validation參數校驗(27)
- springboot集成mybatisPlus(28)
- springboot集成shiro(29)
- springboot實現接口等冪次校驗(30)
- springboot-集成WebSockets(31)
- restTemplate源碼解析(32)
- SpringBoot使用@Async異步調用與線程池(33)
- 待續