当前位置: 首页 > 科技观察

SpringBoot下如何校验SpringMVC请求参数以及如何自定义校验注解

时间:2023-03-18 16:17:12 科技观察

在Java世界中,JavaBean校验的标准规范是JSR380,也称为BeanValidation2.0。JSR380的实现是HibernateValidator。SpringBoot提供了spring-boot-starter-validation来提供对Bean验证的支持。我们可以通过一系列的验证注解来验证JavaBean的属性。本文将演示如何验证SpringMVC的请求参数。当然它可以用于任何JavaBean的验证。让我们先创建一个新的演示项目。请注意,除了添加“SpringWeb”依赖之外,还需要添加额外的“Validation”依赖。SpringBoot2.3之后,我们需要显式添加这个依赖。常用的JSR380注解以及如何验证请求DTO@DatapublicclassPersonDto{@NotNull(message="Thenamecannotbeempty")privateStringname;@Min(value=18,message="最小的18岁")@Max(value=60,message="最大的60")privateIntegerage;@Email(message="Addresscanonlybeemail")privateStringemail;}在JavaBeanDTO上使用JSR380注解,主要注解有:@NotNull:验证注解的属性不能为null@AssertTrue:的属性验证注解为true@Size:验证大小范围在min和max之间,可以是String、Collection、Map、数组属性@Min:验证注解属性的最小值不能小于设置值@Max:验证注解的属性最大值不能大于设置值@Pattern:验证当前字符串属性是否符合指定的正则表达式@Email:验证注解的属性是一个有效的Email地址@NotEmpty:验证注解的属性不能为null或空,所以是String、Collection、Map、数组属性@NotBlank:验证文本属性不为null或空@Positive和@PositiveOrZero:验证整数是正数/正数还是0@Negativeand@NegativeOrZero:检查整数是负数/负数还是0@Pastand@PastOrPresent:检查日期是过去/过去还是现在@Futureand@FutureOrPresent:检查日期是未来/futureorpresentNote在上面的“message”中,设置错误信息。controller如何生效以及如何校验请求参数@RestController@RequestMapping("/people")@Validated//2publicclassPersonController{@PostMappingpublicStringsave(@Valid@RequestBodyPersonDtopersonDto){//1return"OK";}@GetMapping("/findByAge")//2publicStringfindByAge(@Range(min=18,max=60,message="agecanonlybebetween18and60")Integerage){return"OK";}}1。验证DTO只需要在@RequestBody前加上注解“@Valid”即可。如果发生验证错误,将抛出MethodArgumentNotValidException。2.验证请求中的参数(包括路径变量),我们需要在类上注解“@Validated”才会生效。如果存在验证错误,将抛出ConstraintViolationException。这里的@Range注解来自HibernateValidator,一个非标准的JSR380注解。全局异常处理,给前端友好的验证提示。当出现验证错误时,SpringBoot只会抛出异常,所以为了让前端处理这些异常更加友好,我们对这些抛出的异常进行处理。@RestControllerAdvice公共类CustomExceptionHandler{@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(MethodArgumentNotValidException.class)publicMapvalidationExceptionHandler(MethodArgumentNotValidExceptionex){MapMapult;indexors(Hashr)().getAllErrors().forEach((error)->{StringfieldName=((FieldError)error).getField();StringerrorMessage=error.getDefaultMessage();errors.put(fieldName,errorMessage);});返回错误;}@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(ConstraintViolationException.class)publicStringvalidationExceptionHandler(ConstraintViolationExceptionex){返回ex.getMessage();自定义检查注解上面我们使用了JSR380和Hibernate注解来验证,这一节我们演示如何自定义验证注解。我们定义一个验证注解“@Enumeration”,在“EnumerationValidator”类中定义验证规则。当前示例的演示功能为:只允许枚举中的值,否则验证失败。注解定义@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy=EnumerationValidator.class)//3public@interfaceEnumeration{Stringmessage()default"Attributescanonlycomefromthelist";//1字符串[]值();//2Class[]groups()default{};类[]payload()default{};}1.message属性定义错误信息2.values设置可选的枚举值3、通过“@Constraint”指定要验证的类注:如果有没有groups()和payload(),会报:javax.validation.constraintdefinitionexception:hv000074validationlogicclasspublicclassEnumerationValidatorimplementsConstraintValidator{privateStringmessage;私有列表允许;@Overridepublicvoidinitialize(Enumerationenumeration){this.message=enumeration.message();this.allowable=Arrays.asList(enumeration.values());}@OverridepublicbooleanisValid(Stringvalue,ConstraintValidatorContextcontext){returnthis.allowable.contains(value);}}这里的逻辑很简单,只是可选的枚举值需要包含要验证的值。在controller中,当然也配合类上的“@Validated”注解@GetMapping(“/findByGender”)publicStringfindByGender(@Enumeration(values={"Male","Female"},message="性别只能是男或女")Stringgender){return"OK";}开始验证结果:感谢支持我的书《从企业级开发到云原生微服务:Spring Boot实战》。参考:https://medium.com/codex/spring-boot-create-custom-annotation-to-validate-request-parameter-dcf483539d90https://www.baeldung.com/spring-boot-bean-validationhttps://reflectoring.io/bean-validation-with-spring-boot/文章来自:热爱科学的Wesley,如需转载本文,请联系热爱科学的Wesley今天头条号。