Spring?Boot集成validation實(shí)現(xiàn)參數(shù)校驗(yàn)功能
1.什么是Bean Validation?
Bean Validation 是一個(gè)運(yùn)行時(shí)的數(shù)據(jù)驗(yàn)證框架,在驗(yàn)證之后驗(yàn)證的錯(cuò)誤信息會被馬上返回。java 在2009年的 JAVAEE 6 中發(fā)布了 JSR303以及javax下的validation包內(nèi)容。這項(xiàng)工作的主要目標(biāo)是為java應(yīng)用程序開發(fā)人員提供 基于java對象的 約束(constraints)聲明 和 對約束的驗(yàn)證工具(validator),以及約束元數(shù)據(jù)存儲庫和查詢API。但是該內(nèi)容并沒有具體的實(shí)現(xiàn), Hibernate-Validator框架 提供了 JSR 303 規(guī)范中所有內(nèi)置 constraint 的實(shí)現(xiàn),除此之外還有一些附加的 constraint。
常用的Validation注解
一些最常見的驗(yàn)證注解如下:
@NotNull
: 標(biāo)記字段不能為null
@NotEmpty
: 標(biāo)記集合字段不為空(至少要有一個(gè)元素)@NotBlank
: 標(biāo)記字段串字段不能是空字符串(即它必須至少有一個(gè)字符)@Min
/@Max
: 標(biāo)記數(shù)字類型字段必須大于/小于指定的值@Pattern
: 標(biāo)記字符串字段必須匹配指定的正則表達(dá)式@Email
: 標(biāo)記字符串字段必須是有效的電子郵件地址
2.代碼工程
實(shí)驗(yàn)?zāi)繕?biāo):校驗(yàn)controller傳遞的參數(shù)
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springboot-demo</artifactId> <groupId>com.et</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>validtion</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency> </dependencies> </project>
controller
Spring 自動將傳入的 JSON 映射到 Java 對象參數(shù)上。 現(xiàn)在,我們要校驗(yàn)傳入的 Java 對象是否滿足我們預(yù)先定義的約束條件。 為了校驗(yàn)傳入 HTTP 請求的請求實(shí)體,我們在 REST 控制器中使用 @Valid
注解對請求實(shí)體進(jìn)行標(biāo)記:
package com.et.validation.controller; import cn.hutool.json.JSON; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.et.validation.entity.UserInfoReq; import com.fasterxml.jackson.databind.util.JSONPObject; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class HelloWorldController { @RequestMapping("/hello") public Map<String, Object> showHelloWorld(@RequestBody @Validated UserInfoReq req){ Map<String, Object> map = new HashMap<>(); map.put("msg", JSONUtil.toJsonStr(req)); return map; } }
enttiy
我們有一個(gè) int類型 字段,它的值必須介于 1 和 10200之間,如@Min
和@Max
注解所定義的那樣。 我們還有一個(gè) String 類型字段,它必須是一個(gè) IP 地址,正如@Pattern
注解中的正則表達(dá)式所定義的那樣(正則表達(dá)式實(shí)際上仍然允許大于 255 的無效 IP 地址,但在我們創(chuàng)建自定義驗(yàn)證器時(shí),我們將在本教程的后面修復(fù)這個(gè)BUG)。
package com.et.validation.entity; import com.et.validation.validate.IpAddress; import lombok.Data; import lombok.ToString; import javax.validation.constraints.*; @Data @ToString public class UserInfoReq { @NotNull(message = "id不能為null") private Long id; @NotBlank(message = "username不能為空") private String username; @NotNull(message = "age不能為null") @Min(value = 1, message = "年齡不符合要求") @Max(value = 200, message = "年齡不符合要求") private Integer age; @Email(message = "郵箱不符合規(guī)范") private String email; @IpAddress(message = "ip不符合規(guī)范") //@Pattern(regexp = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$") private String ip; }
自定義error捕獲
當(dāng)校驗(yàn)失敗時(shí),我們通常希望向客戶端返回一條有意義的錯(cuò)誤消息。 為了使客戶端能夠顯示有用的錯(cuò)誤消息,我們應(yīng)該返回一個(gè)統(tǒng)一的數(shù)據(jù)結(jié)構(gòu),其中包含每個(gè)校驗(yàn)失敗的錯(cuò)誤消息。 我們在這里所做的只是從異常中讀取有關(guān)校驗(yàn)失敗信息并將它們轉(zhuǎn)換到我們的 ValidationErrorResponse
數(shù)據(jù)結(jié)構(gòu)中。 請注意@ControllerAdvice
注解,它使得上述類型異常的異常處理機(jī)制對所有Controller全局可用。
package com.et.validation.error; import org.springframework.http.HttpStatus; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; 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; @ControllerAdvice class ErrorHandlingControllerAdvice { @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody ValidationErrorResponse onConstraintValidationException( ConstraintViolationException e) { ValidationErrorResponse error = new ValidationErrorResponse(); for (ConstraintViolation violation : e.getConstraintViolations()) { error.getViolations().add( new Violation(violation.getPropertyPath().toString(), violation.getMessage())); } return error; } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody ValidationErrorResponse onMethodArgumentNotValidException( MethodArgumentNotValidException e) { ValidationErrorResponse error = new ValidationErrorResponse(); for (FieldError fieldError : e.getBindingResult().getFieldErrors()) { error.getViolations().add( new Violation(fieldError.getField(), fieldError.getDefaultMessage())); } return error; } }
package com.et.validation.error; import lombok.Data; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Data public class ValidationErrorResponse implements Serializable { private List<Violation> violations = new ArrayList<>(); }
package com.et.validation.error; import lombok.Data; import java.io.Serializable; @Data public class Violation implements Serializable { private final String fieldName; private final String message; public Violation(String fieldName, String message) { this.fieldName = fieldName; this.message = message; } }
自定義validator
如果官方提供可用的校驗(yàn)注解不能滿足我們的需要,我們自己可以定義一個(gè)自定義校驗(yàn)器。 自定義校驗(yàn)注解需要包含以下要素:
- 參數(shù)
message
, 指定 ValidationMessages.properties 文件中的屬性鍵,用于在校驗(yàn)失敗時(shí)解析提示消息, - 參數(shù)
groups
, 允許定義在何種情況下觸發(fā)此校驗(yàn)(稍后我們將討分組校驗(yàn)) - 參數(shù)
payload
, 允許定義要通過此校驗(yàn)傳遞的Payload(因?yàn)檫@是一個(gè)很少使用的功能,我們不會在本教程中介紹它) - 一個(gè)
@Constraint
注解, 指定實(shí)現(xiàn) ConstraintValidator 接口的校驗(yàn)邏輯類。
校驗(yàn)器的實(shí)現(xiàn)如下所示:
package com.et.validation.validate; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ FIELD }) @Retention(RUNTIME) @Constraint(validatedBy = IpAddressValidator.class) @Documented public @interface IpAddress { String message() default "{IpAddress.invalid}"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; }
package com.et.validation.validate; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Matcher; import java.util.regex.Pattern; class IpAddressValidator implements ConstraintValidator<IpAddress, String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { Pattern pattern = Pattern.compile("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$"); Matcher matcher = pattern.matcher(value); try { if (!matcher.matches()) { return false; } else { for (int i = 1; i <= 4; i++) { int octet = Integer.valueOf(matcher.group(i)); if (octet > 255) { return false; } } return true; } } catch (Exception e) { return false; } } }
以上只是一些關(guān)鍵代碼,所有代碼請參見下面代碼倉庫
代碼倉庫
3.測試
啟動spring boot應(yīng)用
測試參數(shù)校驗(yàn)接口
訪問http://127.0.0.1:8088/hello,返回結(jié)果如下
4.引用
到此這篇關(guān)于Spring Boot集成validation實(shí)現(xiàn)參數(shù)校驗(yàn)功能的文章就介紹到這了,更多相關(guān)Spring Boot集成validation參數(shù)校驗(yàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot + validation 接口參數(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開發(fā)SSM框架具有rest風(fēng)格的SpringMVC
這篇文章主要介紹了java開發(fā)中如何使SSM框架具有rest風(fēng)格的SpringMVC實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10java 設(shè)計(jì)模式之依賴倒置實(shí)例詳解
這篇文章主要介紹了java 設(shè)計(jì)模式之依賴倒置,結(jié)合實(shí)例形式詳細(xì)分析了依賴倒置的相關(guān)概念、原理、使用技巧及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-11-11Java 高并發(fā)三:Java內(nèi)存模型和線程安全詳解
本文主要介紹Java高并發(fā)內(nèi)存模型和線程安全的資料,這里整理詳細(xì)的資料及1.原子性 2.有序性 3.可見性 4.Happen-Before 5.線程安全的概念,有需要的小伙伴可以參考下2016-09-09SpringSecurity定義多個(gè)過濾器鏈的操作代碼
Spring?Security?是?Spring家族中的一個(gè)安全管理框架。相比與另外一個(gè)安全框架Shiro,它提供了更豐富的功能,社區(qū)資源也比Shiro豐富,今天通過本文給大家介紹SpringSecurity定義多個(gè)過濾器鏈的實(shí)例,感興趣的朋友跟隨小編一起看看吧2023-04-04