詳解SpringBoot中的參數校驗(項目實戰)
Java后端發工作中經常會對前端傳遞過來的參數做一些校驗,在業務中還要拋出異常或者不斷的返回異常時的校驗信息,充滿了if-else這種校驗代碼,在代碼中相當冗長。例如說,用戶注冊時,會校驗手機格式的正確性,用戶名的長度等等。雖說前端也可以做參數校驗,但是為了保證我們API接口的可靠性,以保證最終數據入庫的正確性,后端進行參數校驗不可忽視。 Hibernate Validator 提供了一種統一方便的方式,讓我們快速的實現參數校驗。
Hibernate Validator 使用注解,實現聲明式校驗。而在實現原理上,也是基于 Spring AOP 攔截,實現校驗相關的操作。 javax.validation.constraints 包下,定義了一系列的約束( constraint )注解。文末會貼上一些常用的注解。 如果項目的框架是 spring boot 的話,在 spring-boot-starter-web 中已經包含了 Hibernate-validator 的依賴( 版本<2.3 )。 2.3 以后的版本中 spring-boot-starter-web 已經去除了這個依賴,需要手動引入 Hibernate-validator 依賴,并且有一些變化,因此 2.3.x 的版本暫不研究。本文使用的版本是 2.2.8 。
實戰
1、創建實體類
package com.yese.pojo;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import org.hibernate.validator.constraints.Length;import javax.validation.constraints.*;@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class User { /** * 用戶ID */ @NotNull(message = '用戶id不能為空') private Long userId; /** * 用戶名 */ @NotBlank(message = '用戶名不能為空') @Length(max = 20, message = '用戶名不能超過10個字符') @Pattern(regexp = '^[u4E00-u9FA5A-Za-z0-9*]*$', message = '用戶名限制:最多10字符,包含文字、字母和數字') private String username; /** * 密碼 */ @NotBlank(message = '密碼不能為空') private String password; /** * 手機號 */ @NotBlank(message = '手機號不能為空') @Pattern(regexp = '^[1][3,4,5,6,7,8,9][0-9]{9}$', message = '手機號格式有誤') private String mobile; /** * 性別 */ @NotNull(message = '性別不能為空') private Integer sex; /** * 年齡 */ @NotNull(message = '年齡不能為空') @Min(value = 1, message = '年齡最小為1歲') @Max(value = 120, message = '年齡最大為120歲') private Integer age; /** * 郵箱 */ @NotBlank(message = '郵箱不能為空') @Email(message = '郵箱格式錯誤') private String email;}
2、創建controller
package com.yese.controller;import com.yese.pojo.User;import lombok.extern.slf4j.Slf4j;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;@RestController@Slf4jpublic class UserController { /** * controller方法的入參里面在實體類前面加上@Validated */ @PostMapping('/user') public void add(@RequestBody @Validated User user) { log.info('user====={}', user); }}
3、創建全局異常處理器
package com.yese.config;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolationException;import java.util.HashMap;import java.util.Map;import java.util.StringJoiner;/** * 全局異常處理器 */@RestControllerAdvicepublic class GlobalExceptionHandler { /** * post方式提交json數據,參數校驗失敗后,會拋出一個MethodArgumentNotValidException */ @ExceptionHandler(MethodArgumentNotValidException.class) public Map<String, Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { // 獲取所有的錯誤 // List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors(); // 獲取錯誤提示 // System.out.println(fieldErrors.get(0).getDefaultMessage()); // 獲取錯誤字段 // System.out.println(fieldErrors.get(0).getField()); // 將所有的錯誤提示使用';'拼接起來并返回 StringJoiner sj = new StringJoiner(';'); e.getBindingResult().getFieldErrors().forEach(x -> sj.add(x.getDefaultMessage())); // 此處通常定義一個全局相應對象返回 Map<String, Object> map = new HashMap<>(); // 此處狀態碼可以通過枚舉或者常量定義 map.put('code', 1001); map.put('msg', sj.toString()); return map; } /** * get方式提交參數,參數校驗失敗后,會拋出一個ConstraintViolationException */ @ExceptionHandler(ConstraintViolationException.class) public Map<String, Object> handleConstraintViolationException(ConstraintViolationException e) { StringJoiner sj = new StringJoiner(';'); e.getConstraintViolations().forEach(x -> sj.add(x.getMessage())); Map<String, Object> map = new HashMap<>(); map.put('code', 1001); map.put('msg', sj.toString()); return map; }}
4、測試
效果符合預期!
@Valid和@Validated
絕大多數場景下,我們使用 @Validated 注解即可。
而在有嵌套校驗的場景,我們使用 @Valid 注解添加到成員屬性上。
附常用注解
javax.validation.constraints 包下
注解 驗證的數據類型 說明 @Null 任意類型 驗證注解的元素值必須是null @NotNull 任意類型 驗證注解的元素值不是null @NotBlank 字符串 驗證注解的元素值不為空(不為null、去除首位空格后長度大于0) @NotEmpty CharSequence子類型、Collection、Map、數組 驗證注解的元素值不為null且不為空(字符串長度不為0、集合大小不為0) @Min(value=值) 數值類型 驗證注解的元素值大于等于@Min指定的value值 @Max(value=值) 和@Min要求一樣 驗證注解的元素值小于等于@Max指定的value值 @DecimalMin(value=值) 和@Min要求一樣 驗證注解的元素值大于等于@ DecimalMin指定的value值 @DecimalMax(value=值) 和@Min要求一樣 驗證注解的元素值小于等于@ DecimalMax指定的value值 @Digits(integer=整數位數, fraction=小數位數) 和@Min要求一樣 驗證注解的元素值的整數位數和小數位數上限 @Size(min=下限, max=上限) 字符串、Collection、Map、數組等 驗證注解的元素值的在min和max(包含)指定區間之內,如字符長度、集合大小 @Positive 判斷正數 @PositiveOrZero 判斷正數或 0 。 @Negative 判斷負數。 @NegativeOrZero 判斷負數或 0 。 @Past 日期類型 驗證注解的元素值(日期類型)比當前時間早 @Future 與@Past要求一樣 驗證注解的元素值(日期類型)比當前時間晚 @AssertFalse Boolean 驗證注解的元素值是false @AssertTrue Boolean 驗證注解的元素值是true @Range(min=最小值, max=最大值) BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型 驗證注解的元素值在最小值和最大值之間 @Email 字符串 驗證注解的元素值是Email,也可以通過regexp和flag指定自定義的email格式 @Pattern(regexp=正則表達式,flag=標志的模式) 字符串 驗證注解的元素值與指定的正則表達式匹配 @Valid 任何非原子類型 指定遞歸驗證關聯的對象如用戶對象中有個地址對象屬性,如果想在驗證用戶對象時一起驗證地址對象的話,在地址對象上加@Valid注解即可級聯驗證
org.hibernate.validator.constraints 包下,定義了一系列的約束( constraint )注解。如下:
@Range(min=, max=) :被注釋的元素必須在合適的范圍內。
@Length(min=, max=) :被注釋的字符串的大小必須在指定的范圍內。
@URL(protocol=,host=,port=,regexp=,flags=) :被注釋的字符串必須是一個有效的 URL 。
@SafeHtml :判斷提交的 HTML 是否安全。例如說,不能包含 javascript 腳本等等。
到此這篇關于詳解SpringBoot中的參數校驗(項目實戰)的文章就介紹到這了,更多相關SpringBoot 參數校驗內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
