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ù)庫就可能導(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 |
長度必須在指定范圍內(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-02
Java編程發(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語言。由于多種原因,綠色計(jì)劃逐漸陷于停滯狀態(tài)2017-03-03
Spring使用@Filter注解創(chuàng)建自定義過濾器
Spring 中鮮為人知但非常有用的注解之一是 @Filter,它支持自定義過濾器,下面我們就來深入研究一下如何使用 Spring 的 @Filter 注解來創(chuàng)建自定義過濾器吧2023-11-11

