估計不少朋友都認爲參數校驗是客戶端的職責,不關服務端的事。其實這是錯誤的,學過 Web 安全的都知道,客戶端的驗證只是第一道關卡。它的參數驗證並非安全的,一旦被有心人抓到可乘之機,他就能夠有各類方法來摸擬系統的 Http 請求,訪問數據庫的關鍵數據。輕則致使服務器宕機,重則泄露數據。因此,這時就須要設置第二道關卡,服務端驗證了。前端
@RestController @RequestMapping("/student") public class ValidateOneController { @GetMapping("/id") public Student findStudentById(Integer id){ if(id == null){ logger.error("id 不能爲空!"); throw new NullPointerException("id 不能爲空"); } return studentService.findStudentById(id); } }
看以上代碼,就一個的校驗就如此麻煩。那咱們是否有好的統一校驗方法呢?鑑於 SpringBoot 無所不能。答案固然是有的。java
其中,Bean Validator 和 Hibernate Validator 就是兩套用於驗證的框架,兩者都遵循 JSR-303 ,能夠混着用,鑑於兩者的某些 Validator 註解有差異,例如 @Length 在 Bean Validator 中是沒有的,因此這裏我選擇混合用。git
JSR-303 是JAVA EE 6 中的一項子規範,叫作 Bean Validation,Hibernate Validator 是 Bean Validation 的參考實現, Hibernate Validator 提供了 JSR 303 規範中全部內置 Constraint(約束) 的實現,除此以外還有一些附加的 Constraint 。這些 Constraint (約束) 全都經過註解的方式實現,請看下面兩個表。github
Bean Validation 中內置的約束:web
註解 | 做用 |
---|---|
@Null | 被註解參數必須爲空 |
@NotNull | 被註解參數不能爲空 |
@AssertTrue | 被註解參數必須爲 True |
@AssertFalse | 被註解參數必須爲 False |
@Min(value) | 被註解參數必須是數字,且其值必須大於等於 value |
@Max(value) | 被註解參數必須是數字,且其值必須小於等於 value |
@DecimaMin(value) | 被註解參數必須是數字,且其值必須大於等於 value |
@DecimaMax(value) | 被註解參數必須是數字,且其值必須小於等於 value |
@Size(max, min) | 被註解參數大小必須在指定範圍內 |
@Past | 被註解參數必須是一個過去的日期 |
@Future | 被註解參數必須是一個未來的日期 |
@Pattern(value) | 被註解參數必須符合指定的正則表達式 |
@Digits(integer, fraction) | 被註解參數必須是數字,且其值必須在可接受範圍內 |
@NotBlank | 被註解參數的值不爲空(不爲 null、去除首位空格後長度爲 0),不一樣於 @NotEmpty,@NotBlank 只應用於字符串且在比較時會去除字符串的空格 |
Hibernate Validator 附加的約束:正則表達式
註解 | 做用 |
---|---|
@NotEmpty | 被註解參數的值不爲 null 且不爲空(字符串長度不爲0、集合大小不爲0) |
被註解參數必須是電子郵箱地址 | |
@Length | 被註解的字符串長度必須在指定範圍內 |
@Range | 被註解的參數必須在指定範圍內 |
<!-- web 啓動類 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- test 單元測試類 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- lombok 依賴用於簡化 bean --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
用於測試,加入了參數校驗規則。算法
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private Integer id; @NotBlank(message = "學生名字不能爲空") @Length(min = 2, max = 10, message = "name 長度必須在 {min} - {max} 之間") private String name; @NotNull(message = "年齡不容許爲空") @Min(value = 0, message = "年齡不能低於 {value} 歲") private Integer age; }
寫了兩個方法,一個用於校驗普通參數,一個用於校驗對象spring
@Validated //開啓數據校驗,添加在類上用於校驗方法,添加在方法參數中用於校驗參數對象。(添加在方法上無效) @RestController @RequestMapping("/student") public class ValidateOneController { /** * 普通參數校驗 * @param name * @return */ @GetMapping("/name") public String findStudentByName(@NotBlank(message = "學生名字不能爲空") @Length(min = 2, max = 10, message = "name 長度必須在 {min} - {max} 之間")String name){ return "success"; } /** * 對象校驗 * @param student * @return */ @PostMapping("/add") public String addStudent(@Validated @RequestBody Student student){ return "success"; } }
校驗普通參數測試結果:數據庫
下圖能夠看見,我沒有在 http://localhost:8080/student/name 地址後添加 name 參數,傳到後臺立刻就校驗出異常了。而這個異常信息就是我定義的校驗異常信息。安全
校驗對象測試結果:
結果有點長:
下圖能夠看見,我訪問 http://localhost:8080/student/add 傳入了參數對象,但對象是不能經過校驗規則的,好比 age 參數爲負數,name 參數長度太大,傳到後臺立刻就校驗出異常了。而這個異常信息就是我定義的校驗異常信息。
https://github.com/turoDog/De...
若是以爲對你有幫助,請給個 Star 再走唄,很是感謝。
若是本文對你哪怕有一丁點幫助,請幫忙點好看。你的好看是我堅持寫做的動力。
另外,關注以後在發送 1024 可領取免費學習資料。
資料詳情請看這篇舊文:Python、C++、Java、Linux、Go、前端、算法資料分享