詳解Springboot如何優(yōu)雅的進(jìn)行數(shù)據(jù)校驗(yàn)
引入依賴(lài)
首先只需要給項(xiàng)目添加上 spring-boot-starter-web 依賴(lài)就夠了,它的子依賴(lài)包含了我們所需要的東西。
注意: Spring Boot 2.3 1 之后,spring-boot-starter-validation 已經(jīng)不包括在了 spring-boot-starter-web 中,需要我們手動(dòng)加上!
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
驗(yàn)證 Controller 的輸入
一定一定不要忘記在類(lèi)上加上 @ Validated 注解了,這個(gè)參數(shù)可以告訴 Spring 去校驗(yàn)方法參數(shù)。
驗(yàn)證請(qǐng)求體
驗(yàn)證請(qǐng)求體即使驗(yàn)證被 @RequestBody 注解標(biāo)記的方法參數(shù)。
PersonController
我們?cè)谛枰?yàn)證的參數(shù)上加上了@Valid注解,如果驗(yàn)證失敗,它將拋出MethodArgumentNotValidException。默認(rèn)情況下,Spring 會(huì)將此異常轉(zhuǎn)換為 HTTP Status 400(錯(cuò)誤請(qǐng)求)。
@RestController @RequestMapping("/api/person") @Validated public class PersonController { @PostMapping public ResponseEntity<PersonRequest> save(@RequestBody @Valid PersonRequest personRequest) { return ResponseEntity.ok().body(personRequest); } }
@Data @Builder @AllArgsConstructor @NoArgsConstructor public class PersonRequest { @NotNull(message = "classId 不能為空") private String classId; @Size(max = 33) @NotNull(message = "name 不能為空") private String name; @Pattern(regexp = "(^Man$|^Woman$|^UGM$)", message = "sex 值不在可選范圍") @NotNull(message = "sex 不能為空") private String sex; }
使用 Postman 驗(yàn)證
驗(yàn)證請(qǐng)求參數(shù)
驗(yàn)證請(qǐng)求參數(shù)(Path Variables 和 Request Parameters)即是驗(yàn)證被 @PathVariable 以及 @RequestParam 標(biāo)記的方法參數(shù)。
PersonController
@RestController @RequestMapping("/api/persons") @Validated public class PersonController { @GetMapping("/{id}") public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5, message = "超過(guò) id 的范圍了") Integer id) { return ResponseEntity.ok().body(id); } @PutMapping public ResponseEntity<String> getPersonByName(@Valid @RequestParam("name") @Size(max = 6, message = "超過(guò) name 的范圍了") String name) { return ResponseEntity.ok().body(name); } }
使用 Postman 驗(yàn)證
嵌套校驗(yàn)
在一個(gè)校驗(yàn)A對(duì)象里另一個(gè)B對(duì)象里的參數(shù)
需要在B對(duì)象上加上@Valid注解
常用校驗(yàn)注解總結(jié)
JSR303 定義了 Bean Validation(校驗(yàn))的標(biāo)準(zhǔn) validation-api,并沒(méi)有提供實(shí)現(xiàn)。Hibernate Validation是對(duì)這個(gè)規(guī)范/規(guī)范的實(shí)現(xiàn) hibernate-validator,并且增加了 @Email、@Length、@Range 等注解。Spring Validation 底層依賴(lài)的就是Hibernate Validation。
JSR 提供的校驗(yàn)注解:
- @Null 被注釋的元素必須為 null
- @NotNull 被注釋的元素必須不為 null
- @AssertTrue 被注釋的元素必須為 true
- @AssertFalse 被注釋的元素必須為 false
- @Min(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
- @Max(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
- @DecimalMin(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
- @DecimalMax(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
- @Size(max=, min=) 被注釋的元素的大小必須在指定的范圍內(nèi)
- @Digits (integer, fraction) 被注釋的元素必須是一個(gè)數(shù)字,其值必須在可接受的范圍內(nèi)
- @Past 被注釋的元素必須是一個(gè)過(guò)去的日期
- @Future 被注釋的元素必須是一個(gè)將來(lái)的日期
- @Pattern(regex=,flag=) 被注釋的元素必須符合指定的正則表達(dá)式
Hibernate Validator 提供的校驗(yàn)注解:
- @NotBlank(message =) 驗(yàn)證字符串非 null,且長(zhǎng)度必須大于 0
- @Email 被注釋的元素必須是電子郵箱地址
- @Length(min=,max=) 被注釋的字符串的大小必須在指定的范圍內(nèi)
- @NotEmpty 被注釋的字符串的必須非空
- @Range(min=,max=,message=) 被注釋的元素必須在合適的范圍內(nèi)
@JsonFormat與@DateTimeFormat注解的使用
@JsonFormat用于后端傳給前端的時(shí)間格式轉(zhuǎn)換,@DateTimeFormat用于前端傳給后端的時(shí)間格式轉(zhuǎn)換
JsonFormat
1、使用maven引入@JsonFormat所需要的jar包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.8.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.8</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency>
2、在需要查詢(xún)時(shí)間的數(shù)據(jù)庫(kù)字段對(duì)應(yīng)的實(shí)體類(lèi)的屬性上添加@JsonFormat
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateDate;
注: timezone:是時(shí)間設(shè)置為東八區(qū),避免時(shí)間在轉(zhuǎn)換中有誤差,pattern:是時(shí)間轉(zhuǎn)換格式
DataTimeFormat
1、添加依賴(lài)
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.3</version> </dependency>
2、我們?cè)趯?duì)應(yīng)的接收前臺(tái)數(shù)據(jù)的對(duì)象的屬性上加@DateTimeFormat
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime acquireDate;
3.這樣我們就可以將前端獲取的時(shí)間轉(zhuǎn)換為一個(gè)符合自定義格式的時(shí)間格式存儲(chǔ)到數(shù)據(jù)庫(kù)了 全局異常統(tǒng)一處理:攔截并處理校驗(yàn)出錯(cuò)的返回?cái)?shù)據(jù) 寫(xiě)一個(gè)全局異常處理類(lèi)
@ControllerAdvice public class GlobalExceptionHandler{ /** * 處理參數(shù)校驗(yàn)異常 */ @ExceptionHandler({MethodArgumentNotValidException.class}) @ResponseBody public ErrorResponseData validateException(MethodArgumentNotValidException e) { log.error("參數(shù)異常"+e.getBindingResult().getFieldError().getDefaultMessage(),e); return new ErrorResponseData(10001,e.getBindingResult().getFieldError().getDefaultMessage()); } /** * 處理json轉(zhuǎn)換異常(比如 @DateTimeFormat注解轉(zhuǎn)換日期格式時(shí)) */ @ExceptionHandler({HttpMessageNotReadableException.class}) @ResponseBody public ErrorResponseData jsonParseException(HttpMessageNotReadableException e) { log.error("參數(shù)異常"+e.getLocalizedMessage(),e); return new ErrorResponseData(10001,e.getCause().getMessage()); } }
以上就是詳解Springboot如何優(yōu)雅的進(jìn)行數(shù)據(jù)校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于Springboot 數(shù)據(jù)校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
spring boot整合spring-kafka實(shí)現(xiàn)發(fā)送接收消息實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于spring-boot整合spring-kafka實(shí)現(xiàn)發(fā)送接收消息的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)看看吧。2017-06-06SpringMVC中ModelAndView用法小結(jié)
本文主要介紹了SpringMVC中ModelAndView用法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的方法總結(jié)
項(xiàng)目開(kāi)發(fā)中經(jīng)常會(huì)遇到多數(shù)據(jù)源同時(shí)使用的場(chǎng)景,比如冷熱數(shù)據(jù)的查詢(xún)等情況,所以接下來(lái)本文就來(lái)介紹一下如何使用實(shí)現(xiàn)自定義注解的形式來(lái)實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換吧2023-12-12Spring高階用法之自定義業(yè)務(wù)對(duì)象組件化
這篇文章主要介紹了Spring高階用法之自定義業(yè)務(wù)對(duì)象組件化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03IDEA2020 Plugins不能用的解決辦法及Plugins 搜索不了插件的問(wèn)題
這篇文章主要介紹了IDEA2020 Plugins不能用的解決辦法,文中給大家介紹了Intellij IDEA 2020.1 的Plugins 搜索不了插件,連接超時(shí)的問(wèn)題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-06-06Java中的遞增i++與++i的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中的i++與++i的實(shí)現(xiàn)原理詳解,在Java中,i++是一種常見(jiàn)的遞增操作符,用于將變量i的值增加1,它是一種簡(jiǎn)潔且方便的方式來(lái)實(shí)現(xiàn)循環(huán)和計(jì)數(shù)功能,i++可以用于各種情況,本文來(lái)看一下其實(shí)現(xiàn)原理,需要的朋友可以參考下2023-10-10SpringBoot集成Redis使用Cache緩存的實(shí)現(xiàn)方法
SpringBoot通過(guò)配置RedisConfig類(lèi)和使用Cache注解可以輕松集成Redis實(shí)現(xiàn)緩存,主要包括@EnableCaching開(kāi)啟緩存,自定義key生成器,改變序列化規(guī)則,以及配置RedisCacheManager,本文為使用SpringBoot與Redis處理緩存提供了詳實(shí)的指導(dǎo)和示例,感興趣的朋友一起看看吧2024-10-10SpringBoot構(gòu)建RESTful API的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot構(gòu)建RESTful API的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05idea無(wú)法切換分支報(bào)錯(cuò)問(wèn)題及解決
這篇文章主要介紹了idea無(wú)法切換分支報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03springboot+vue實(shí)現(xiàn)登錄功能的最新方法整理
最近做項(xiàng)目時(shí)使用到了springboot+vue實(shí)現(xiàn)登錄功能的技術(shù),所以下面這篇文章主要給大家介紹了關(guān)于springboot+vue實(shí)現(xiàn)登錄功能的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06