個人博客:蘭陵笑笑生,歡迎瀏覽博客!java
上一章 SpringBoot入門實踐(五)-開源日誌框架介紹當中,咱們介紹了經常使用的開源日誌框架。本期總結我在項目中是如何使用JSR實現請求參數的驗證的。git
從Spring4開始,已經實現了對JSR-349(Bean Validation,是JSR303的升級 )的全面支持,Bean Validation API在javax。validation.CONSTRAINTS 中以JAVA註解的形式定義了一組可應用於域對象的約束,另外可使用註解開發和應用自定義驗證器,如類級驗證器。web
public class Singer { @NotNull(message = "名稱不能爲空") @Size(min = 2, max = 5) private String fistName; private String lastName; @NotNull(message = "性別不能爲空") private Genre genre; .... }
package com.miroservice.chapter2.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;@Configuration@ComponentScan("com.miroservice") public class AppConfig { /** * 默認會在類路徑下搜索Hibernate validator的庫 * @return */ @Bean LocalValidatorFactoryBean validator(){ return new LocalValidatorFactoryBean(); } }
import com.miroservice.chapter2.pojo.Singer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.validation.ConstraintViolation;import javax.validation.Validator;import java.util.Set; @Component public class ValidateComponent { /** * 注入一個javax.validation.Validator 實例 */ @Autowired private Validator validator; public Set<ConstraintViolation<Singer>> validatorSinger(Singer singer) { return validator.validate(singer); } }
package com.miroservice.chapter2.web; import com.miroservice.chapter2.config.AppConfig; import com.miroservice.chapter2.pojo.Singer; importorg.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.GenericApplicationContext; import javax.validation.ConstraintViolation; import java.util.Set; public class JSR349Demo { public static void main(String[] args) { GenericApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); ValidateComponent validateController = ctx.getBean(ValidateComponent.class); Singer singer = new Singer(); singer.setFistName("j"); singer.setLastName("l"); singer.setGenre(null); validatorSinger(singer, validateController); } private static void validatorSinger(Singer singer, ValidateComponent validateController) { final Set<ConstraintViolation<Singer>> constraintViolations = validateController.validatorSinger(singer); listVidlations(constraintViolations); } private static void listVidlations(Set<ConstraintViolation<Singer>> set) { for (ConstraintViolation<Singer> v : set) { System.out.print("property:" + v.getPropertyPath() + ",value:" + v.getInvalidValue() + ";error:" + v.getMessage()); } } }
import javax.validation.constraints.NotNull;import javax.validation.constraints.Size; public class Singer { @NotNull(message = "名稱不能爲空") @Size(min = 2, max = 5) private String fistName; private String lastName; @NotNull(message = "性別不能爲空") private Genre genre; ... }
import com.miroservice.chapter2.common.HttpResponse; import com.miroservice.chapter2.pojo.Singer; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @RestController public class SingerController { /** * 添加@Valid 註解 * @param singer * @return */ @PostMapping("/singer") private String validator(@Valid @RequestBody Singer singer) { System.out.print(singer); return "ok"; }
{ "fistName":null, "genre":"FEMALE" }
{ "timestamp": "2020-01-11T15:16:22.851+0000", "status": 400, "error": "Bad Request", "errors": [ { "codes": [ "NotNull.singer.fistName", "NotNull.fistName", "NotNull.java.lang.String", "NotNull" ], "arguments": [ { "codes": [ "singer.fistName", "fistName" ], "arguments": null, "defaultMessage": "fistName", "code": "fistName" } ], "defaultMessage": "名稱不能爲空", "objectName": "singer", "field": "fistName", "rejectedValue": null, "bindingFailure": false, "code": "NotNull" } ], "message": "Validation failed for object='singer'. Error count: 1", "path": "/singer" }
入參的第二個地方,綁定BindingResult,當Bean中屬性不知足是,能夠獲取到註解上的信息,並放回到正則表達式
自定義的結果中。spring
@PostMapping("/singer") private HttpResponse validator(@Valid @RequestBody Singer singer, BindingResult result) { if (result.hasErrors()) { return HttpResponse.error(result.getFieldError().getDefaultMessage()); } return HttpResponse.ok(); }
{ "code": 500, "message": "名稱不能爲空", "requestid": "eebb0bf86dc24aabb9051bf832542828" }
對於一些複雜的驗證,好比說手機號碼的驗證,須要多個條件,或者一個驗證的POJO中包含了另外一個類,出現了這樣的需求也是常有的,這就須要咱們自定義建立驗證器了,以手機的長度爲例,咱們自定義一個手機號的驗證。json
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Documented //使用的驗證器,自定義驗證器 @Constraint(validatedBy = PhoneValidator.class) //註解的使用級別是方法、屬性上 @Target({ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Phone { //若是 驗證通過PhoneValidator的驗證返回false ,則默認返回的信息 String message() default "長度必須大於11"; /** * * @return */ Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {} ; }
package com.miroservice.chapter2.pojo; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; /** * 自定義實現對phone的驗證邏輯 */ public class PhoneValidator implements ConstraintValidator<Phone,String> { /** * value就是屬性 * */ @Override public boolean isValid(String value, ConstraintValidatorContext context) { if(value==null||value.trim().length()<12){ return false; }else { return true; } } }
public class Singer { @NotNull(message = "名稱不能爲空") @Size(min = 2, max = 5) private String fistName; private String lastName; @NotNull(message = "性別不能爲空") private Genre genre; @Phone() private String phone; ... }
請求參數segmentfault
{ "phone" : 1, "fistName": "zhang", "genre":"MALE" }
請求結果app
{ "code": 500, "message": "長度必須大於11", "requestid": "38cc357c07144d098e7c5730cc8f4c08" }
以上就是本期的分享,你還能夠關注本博客的#Spring Boot入門實踐系列!#框架
本文由博客一文多發平臺 OpenWrite 發佈!
個人博客[蘭陵笑笑生] ( http://www.hao127.com.cn/),歡...!