javascript
SpringBoot - 优雅的实现【参数校验】高级进阶
文章目錄
- Pre
- 概述
- 參數(shù)校驗(yàn)三部曲
- Step1 搞依賴
- Step2 搞參數(shù)校驗(yàn)的實(shí)體類
- 常用的校驗(yàn)注解
- Step3 開(kāi)始驗(yàn)證
- 存在的問(wèn)題
- 使用 統(tǒng)一格式 + 全局異常Handler 優(yōu)化
- 源碼
Pre
SpringBoot - 優(yōu)雅的實(shí)現(xiàn)【參數(shù)校驗(yàn)】高級(jí)進(jìn)階
SpringBoot - 優(yōu)雅的實(shí)現(xiàn)【自定義參數(shù)校驗(yàn)】高級(jí)進(jìn)階
SpringBoot - 優(yōu)雅的實(shí)現(xiàn)【參數(shù)分組校驗(yàn)】高級(jí)進(jìn)階
SpringBoot - 使用Assert校驗(yàn)讓業(yè)務(wù)代碼更簡(jiǎn)潔
概述
日常開(kāi)發(fā)中,對(duì)入?yún)⑦M(jìn)行參數(shù)校驗(yàn)是必不可少的一個(gè)環(huán)節(jié)。 而使用最多的就是Validator框架 。
Validator校驗(yàn)框架遵循了JSR-303 【Java Specification Requests】驗(yàn)證規(guī)范 。
這里我們探討下,在boot項(xiàng)目中如何優(yōu)雅的集成參數(shù)校驗(yàn)框架
參數(shù)校驗(yàn)三部曲
Step1 搞依賴
boot 2.3 以后版本的pom信息如下
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency></dependencies>- spring boot-2.3之前的版本只需要引入 spring-boot-starter-web 即可 ,已經(jīng)包含了
- spring boot-2.3及以后的版本,校驗(yàn)包是一個(gè)單獨(dú)的starter,需要同時(shí)引入spring-boot-starter-validation
Step2 搞參數(shù)校驗(yàn)的實(shí)體類
package com.artisan.vo;import lombok.Data; import org.hibernate.validator.constraints.Length;import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty;/*** @author 小工匠* @version 1.0 * @mark: show me the code , change the world*/@Data public class Artisan {private String id;@NotBlank(message = "名字為必填項(xiàng)")private String name;@Length(min = 8, max = 12, message = "password長(zhǎng)度必須位于8到12之間")private String password;@Email(message = "請(qǐng)?zhí)顚懻_的郵箱地址")private String email;private String sex;@NotEmpty(message = "Code不能為空")private String code; }常用的校驗(yàn)注解
| @AssertFalse | 可以為null,如果不為null的話必須為false |
| @AssertTrue | 可以為null,如果不為null的話必須為true |
| @DecimalMax | 設(shè)置不能超過(guò)最大值 |
| @DecimalMin | 設(shè)置不能超過(guò)最小值 |
| @Digits | 設(shè)置必須是數(shù)字且數(shù)字整數(shù)的位數(shù)和小數(shù)的位數(shù)必須在指定范圍內(nèi) |
| @Future | 日期必須在當(dāng)前日期的未來(lái) |
| @Past | 日期必須在當(dāng)前日期的過(guò)去 |
| @Max | 最大不得超過(guò)此最大值 |
| @Min | 最大不得小于此最小值 |
| @NotNull | 不能為null,可以是空 |
| @Null | 必須為null |
| @Pattern | 必須滿足指定的正則表達(dá)式 |
| @Size | 集合、數(shù)組、map等的size()值必須在指定范圍內(nèi) |
| 必須是email格式 | |
| @Length | 長(zhǎng)度必須在指定范圍內(nèi) |
| @NotBlank | 字符串不能為null,字符串trim()后也不能等于“” |
| @NotEmpty | 不能為null,集合、數(shù)組、map等size()不能為0;字符串trim()后可以等于“” |
| @Range | 值必須在指定范圍內(nèi) |
| @URL | 必須是一個(gè)URL |
Step3 開(kāi)始驗(yàn)證
注意看注釋
package com.artisan.controller;import com.artisan.vo.Artisan; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*;import javax.validation.constraints.Email;/*** @author 小工匠* @version 1.0* @mark: show me the code , change the world*/@RestController @Slf4j @Validated @RequestMapping("/valid") public class ArtisanController {/*** 使用@RequestBody注解,用于接受前端發(fā)送的json數(shù)據(jù)** @param artisan* @return*/@PostMapping("/testJson")public String testJson(@Validated @RequestBody Artisan artisan) {log.info("InComing Param {}", artisan);return "testJson valid success";}/*** 模擬表單提交** @param artisan* @return*/@PostMapping(value = "/testForm")public String testForm(@Validated Artisan artisan) {log.info("InComing Param is {}", artisan);return "testForm valid success";}/*** 模擬單參數(shù)提交** @param email* @return*/@PostMapping(value = "/testParma")public String testParma(@Email String email) {log.info("InComing Param is {}", email);return "testParma valid success";}}-
testJson使用 @RequestBody注解,用于接受前端發(fā)送的json數(shù)據(jù)
-
testForm模擬表單提交
-
testParma模擬單參數(shù)提交
當(dāng)使用單參數(shù)校驗(yàn)時(shí)需要在Controller上加上@Validated注解,否則不生效
【測(cè)試第一個(gè)接收J(rèn)SON的接口 】
可以看到拋出的異常為: org.springframework.web.bind.MethodArgumentNotValidException
【測(cè)試第二個(gè)接收表單的接口 】
可以看到拋出的異常為: org.springframework.validation.BindException
【測(cè)試第三個(gè)接收單參數(shù)的接口 】
可以看到拋出的異常為:javax.validation.ConstraintViolationException
存在的問(wèn)題
且不說(shuō)好不好看, 不管怎么樣,現(xiàn)在是通過(guò)Validation框架實(shí)現(xiàn)了校驗(yàn)。 當(dāng)然了,我們的追求肯定不是這樣的,Validator校驗(yàn)框架返回的錯(cuò)誤提示太臃腫了 ,格式啥的都不一樣,很難搞哦, 怎么給前臺(tái)返回????
使用 統(tǒng)一格式 + 全局異常Handler 優(yōu)化
增加統(tǒng)一返回 和 全局異常Handler,單獨(dú)攔截參數(shù)校驗(yàn)的三個(gè)異常:javax.validation.ConstraintViolationException,org.springframework.validation.BindException,org.springframework.web.bind.MethodArgumentNotValidException
/*** @param e* @return*/@ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})public ResponseEntity<ResponseData<String>> handleValidatedException(Exception e) {ResponseData<String> resp = null;if (e instanceof MethodArgumentNotValidException) {// BeanValidation exceptionMethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),ex.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("; ")));} else if (e instanceof ConstraintViolationException) {// BeanValidation GET simple paramConstraintViolationException ex = (ConstraintViolationException) e;resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("; ")));} else if (e instanceof BindException) {// BeanValidation GET object paramBindException ex = (BindException) e;resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),ex.getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("; ")));}log.error("參數(shù)校驗(yàn)異常:{}", resp.getMessage());return new ResponseEntity<>(resp, HttpStatus.BAD_REQUEST);}重新測(cè)試
源碼
https://github.com/yangshangwei/boot2
總結(jié)
以上是生活随笔為你收集整理的SpringBoot - 优雅的实现【参数校验】高级进阶的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SpringBoot - 统一格式封装及
- 下一篇: SpringBoot - 优雅的实现【自