个人博客:兰陵笑笑生,欢迎浏览博客!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/),欢...!