SpringBoot + validation 接口參數(shù)校驗(yàn)的思路詳解
有參數(shù)傳遞的地方都少不了參數(shù)校驗(yàn)。在web開發(fā)中,前端的參數(shù)校驗(yàn)是為了用戶體驗(yàn),后端的參數(shù)校驗(yàn)是為了安全。試想一下,如果在controller層中沒有經(jīng)過任何校驗(yàn)的參數(shù)通過service層、dao層一路來到了數(shù)據(jù)庫(kù)就可能導(dǎo)致嚴(yán)重的后果,最好的結(jié)果是查不出數(shù)據(jù),嚴(yán)重一點(diǎn)就是報(bào)錯(cuò),如果這些沒有被校驗(yàn)的參數(shù)中包含了惡意代碼,那就可能導(dǎo)致更嚴(yán)重的后果。
實(shí)踐
一、引入依賴
<!--引入spring-boot-starter-validation--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
二、使用校驗(yàn)
在controller層的參數(shù)校驗(yàn)可以分為兩種場(chǎng)景:
單個(gè)參數(shù)校驗(yàn)
實(shí)體類參數(shù)校驗(yàn)
2.1 單參數(shù)校驗(yàn)
/** * 參數(shù)校驗(yàn)測(cè)試 控制類 * @author oyc */ @RestController @RequestMapping("user") @Validated public class RequestParamsValidatedController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping public User test(@NotNull(message = "姓名不能為空") String name, @NotNull(message = "年齡不能為空") @Max(value = 99, message = "不能大于200歲") Integer age) { logger.info("name:" + name + " -age:" + age); return new User(name, age); } }
2.2 實(shí)體類參數(shù)校驗(yàn)
/** * 參數(shù)校驗(yàn)測(cè)試 控制類 * @author oyc */ @RestController @RequestMapping("user") @Validated public class RequestParamsValidatedController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @PostMapping public User save(@Validated User user) { logger.info(user.toString()); return user; } }
package com.oycbest.springbootvalidated.vo; import javax.validation.constraints.*; import java.io.Serializable; /** * 用戶實(shí)體類 * @author oyc */ public class User implements Serializable { private String userId; @NotNull(message = "用戶名不能為空") private String userName; @NotNull(message = "年齡不能為空") @Max(value = 100, message = "年齡不能大于100歲") private int age; @NotNull(message = "郵箱不能為空") @Email(message = "郵箱格式不正確") private String email; @NotNull(message = "電話號(hào)碼不能為空") private String phoneNumber; public User(@NotNull(message = "用戶名不能為空") String userName, int age) { this.userName = userName; this.age = age; } public User() { } public User(String userId, @NotNull(message = "用戶名不能為空") String userName, int age, String email, String phoneNumber) { this.userId = userId; this.userName = userName; this.age = age; this.email = email; this.phoneNumber = phoneNumber; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Override public String toString() { return "User{" + "userId='" + userId + '\'' + ", userName='" + userName + '\'' + ", age=" + age + ", email='" + email + '\'' + ", phoneNumber='" + phoneNumber + '\'' + '}'; } }
2.3 定義統(tǒng)一異常處理
package com.oycbest.springbootvalidated.exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.List; import java.util.Set; /** * 全局異常處理 * * @author oyc */ @ControllerAdvice @Component public class GlobalExceptionHandler { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public String handle(ValidationException exception) { logger.error("請(qǐng)求異常:" + exception.getMessage()); if (exception instanceof ConstraintViolationException) { ConstraintViolationException exs = (ConstraintViolationException) exception; Set<ConstraintViolation<?>> violations = exs.getConstraintViolations(); for (ConstraintViolation<?> item : violations) { //打印驗(yàn)證不通過的信息 logger.error("請(qǐng)求異常:" + item.getMessage()); } } return "請(qǐng)求異常: " + exception.getMessage(); } @ResponseBody @ExceptionHandler(value = BindException.class) public String bindException(Exception e) { if (e instanceof BindException) { BindException exs = (BindException) e; List<FieldError> fieldErrors = exs.getFieldErrors(); for (FieldError item : fieldErrors) { logger.error("請(qǐng)求異常:" + item.getDefaultMessage()); } } logger.error("數(shù)據(jù)綁定異常:" + e.getMessage()); return "數(shù)據(jù)綁定異常"; } @ResponseBody @ExceptionHandler(value = Exception.class) public String defaultException(Exception e) { logger.error("請(qǐng)求異常:" + e.getMessage()); return "請(qǐng)求異常 " + e.getMessage(); } }
三、約束性注解(簡(jiǎn)單)說明
注解 |
功能 |
@AssertFalse |
可以為null,如果不為null的話必須為false |
@AssertTrue |
可以為null,如果不為null的話必須為true |
@DecimalMax |
設(shè)置不能超過最大值 |
@DecimalMin |
設(shè)置不能超過最小值 |
@Digits |
設(shè)置必須是數(shù)字且數(shù)字整數(shù)的位數(shù)和小數(shù)的位數(shù)必須在指定范圍內(nèi) |
@Future |
日期必須在當(dāng)前日期的未來 |
@Past |
日期必須在當(dāng)前日期的過去 |
@Max |
最大不得超過此最大值 |
@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 |
到此這篇關(guān)于SpringBoot + validation 接口參數(shù)校驗(yàn)的文章就介紹到這了,更多相關(guān)SpringBoot + validation 接口參數(shù)校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring?Boot集成validation實(shí)現(xiàn)參數(shù)校驗(yàn)功能
- SpringBoot使用Validation包進(jìn)行輸入?yún)?shù)校驗(yàn)
- spring?boot?validation參數(shù)校驗(yàn)與分組嵌套各種類型及使用小結(jié)
- springboot中使用Hibernate-Validation校驗(yàn)參數(shù)詳解
- SpringBoot使用Validation進(jìn)行參數(shù)校驗(yàn)的示例詳解
- spring-boot-starter-validation?校驗(yàn)參數(shù)的實(shí)現(xiàn)
- spring boot輸入數(shù)據(jù)校驗(yàn)(validation)的實(shí)現(xiàn)過程
- 從零到掌握Spring Boot Validation 接口校驗(yàn)的詳細(xì)過程
相關(guān)文章
Java實(shí)現(xiàn)銀行ATM系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)銀行ATM系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04基于Springboot+Junit+Mockito做單元測(cè)試的示例
本篇文章主要介紹了基于Springboot+Junit+Mockito做單元測(cè)試的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02Java編程發(fā)展歷史(動(dòng)力節(jié)點(diǎn)Java學(xué)院整理)
Java的歷史可以追溯到1991年4月,Sun公司的James Gosling領(lǐng)導(dǎo)的綠色計(jì)劃(Green Project)開始著力發(fā)展一種分布式系統(tǒng)結(jié)構(gòu),使其能夠在各種消費(fèi)性電子產(chǎn)品上運(yùn)行,他們使用了C/C++/Oak語(yǔ)言。由于多種原因,綠色計(jì)劃逐漸陷于停滯狀態(tài)2017-03-03Spring使用@Filter注解創(chuàng)建自定義過濾器
Spring 中鮮為人知但非常有用的注解之一是 @Filter,它支持自定義過濾器,下面我們就來深入研究一下如何使用 Spring 的 @Filter 注解來創(chuàng)建自定義過濾器吧2023-11-11