做棋牌网站违法吗,盐城网站建设多少钱,wordpress文章添加跳转链接,大型企业展厅设计公司一、Validated 和Valid有什么用
Validation 和Valid 常常配合使用对传输的参数进行数据校验的注解#xff0c;并通过配置全局异常处理器进行合理化的提示#xff0c;增加用户的体验
并且Validated可以通过分组来指定什么时候触发什么样的参数校验#xff08;这里看一下就行…一、Validated 和Valid有什么用
Validation 和Valid 常常配合使用对传输的参数进行数据校验的注解并通过配置全局异常处理器进行合理化的提示增加用户的体验
并且Validated可以通过分组来指定什么时候触发什么样的参数校验这里看一下就行下面有说什么是分组
二、为什么要使用Validated 和Valid的思考
其实不用这两个注解也可以完成对传输的参数进校验那样我们就需要一直写if语句进行判断 如果不为xxx抛出异常然后进行捕获处理
但是当多处都用到的一样的传输参数的时候我们每次都需要写一些重复的if进行校验其实代码是不优雅的。因此有了这两个组件来帮我们进行传输参数的校验。
三、使用方法
3.1 引入pom
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--validator请求参数校验--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!--测试方法--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactId/dependency/dependencies
3.2 写实体类加入一写校验注解
常用的校验注解 package com.sofwin.validator.domain;import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.config.Status;
import com.sofwin.validator.config.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.Mapping;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.List;/*** packageName: com.sofwin.validator.domain* author: wentao* date: 2023/9/4 21:17* version: 1.0* email 1660420659qq.com* description: 测试*/
Data
public class UserR {NotBlank(message 名称不能为空)private String name;NotNull(message 年龄不能为空)Range(min 1,max 200,message 最小为{min}岁最大为{max}岁 )private Integer age;Size(message 编号长度为 [4-8] , min 4, max 8)private String idNo;}3.3 编写controller层进行测试 请求参数是对象
注意需要在请求参数的前面加上Valid注解
统一返回类
package com.sofwin.validator.config;import lombok.Data;/*** packageName: com.sofwin.validator.config* author: wentao* date: 2023/9/4 21:34* version: 1.0* email 1660420659qq.com* description: 统一返回参数*/
Data
public class BaseResultT {private int code;private String message;private T data;public BaseResult() {}public BaseResult(int code, T data,String message) {this.code code;this.message message;this.data data;}public static T BaseResultT build(int code, T data, String message) {return new BaseResultT(code,data,message);}public static T BaseResultT build( T data, BaseResult resultCodeEnum) {return new BaseResultT(resultCodeEnum.getCode(),data,resultCodeEnum.getMessage());}public static T BaseResultT ok(T data) {return new BaseResult(20000,data,success);}public static T BaseResultT fail(T data) {return new BaseResult(50000,data,error);}}controller
package com.sofwin.validator.controller;import com.sofwin.validator.config.BaseResult;
import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.domain.UserR;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;
import javax.validation.constraints.NotNull;/*** packageName: com.sofwin.validator.controller* author: wentao* date: 2023/9/4 21:14* version: 1.0* description: 请求参数校验*/RestController
RequestMapping(validator)
public class ValidatorController {PostMapping(/validPost)public BaseResult validPostTest(Valid RequestBody UserR user ) {return BaseResult.ok(user);}}正常参数 非正常参数 我们发现没有提示我们在实体中message中写的提示信息是因为我们没有设置全局异常处理器
它只是在控制台返回了提示信息 2023-09-05 21:24:03.305 WARN 20924 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.sofwin.validator.config.BaseResult com.sofwin.validator.controller.ValidatorController.validPostTest(com.sofwin.validator.domain.UserR): [Field error in object userR on field age: rejected value [1111]; codes [Range.userR.age,Range.age,Range.java.lang.Integer,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userR.age,age]; arguments []; default message [age],200,1]; default message [最小为1岁最大为200岁]] ] 全局异常处理器
package com.sofwin.validator.config;import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Set;
import org.slf4j.Logger;/*** packageName: com.sofwin.validator.config* author: wentao* date: 2023/9/4 21:28* version: 1.0* email 1660420659qq.com* description: 全局异常处理器*/RestControllerAdvice
Slf4j
public class GlobExceptionHandeler {private final Logger logger LoggerFactory.getLogger(getClass());//valid参数校验出现异常ExceptionHandler(BindException.class)public BaseResult bindException(BindException e) {logger.error(valid参数校验出现异常);System.out.println(e);return BaseResult.build(441,null,e.getBindingResult().getAllErrors().get(0).getDefaultMessage());}//validated参数校验出现异常ExceptionHandler(ConstraintViolationException.class)public BaseResult constraintViolationException(ConstraintViolationException e) {logger.error(validated参数校验出现异常);return BaseResult.build(441,null,e.getLocalizedMessage().split(:)[1].trim());}ExceptionHandler(Exception.class)public BaseResult constraintViolationException(Exception e) {logger.error(Exception);return BaseResult.build(441,null,e.getLocalizedMessage());}
}加入全局异常处理器后非正常参数返回结果 3.4 当参数不是一个对象 一定要在controller上加入Validated才生效
RestController
RequestMapping(validator)
Validated
public class ValidatorController {PostMapping(/validPost)public BaseResult validPostTest(Valid RequestBody UserR user ) {return BaseResult.ok(user);}GetMapping(/validGet1)public BaseResult validGetTest( NotBlank(message 名字不能为空) String name ) {return BaseResult.ok(name);}
} 3.5 分组
当我们在特定情况下才进行参数校验才进行分组例如只有当我们插入的时候我们进行校验其他时候不进行参数的校验这个时候就可以使用分组
实体类
package com.sofwin.validator.domain;import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.config.Status;
import com.sofwin.validator.config.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.Mapping;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.List;/*** packageName: com.sofwin.validator.domain* author: wentao* date: 2023/9/4 21:17* version: 1.0* email 1660420659qq.com* description: 测试*/
Data
public class UserR {NotBlank(message 名称不能为空)//进行分组NotBlank(message 名称不能为空(InsertGroup),groups InsertGroup.class)private String name;NotNull(message 年龄不能为空)NotNull(message 年龄不能为空(InsertGroup),groups {InsertGroup.class,UpdateGroup.class})Range(min 1,max 200,message 最小为{min}岁最大为{max}岁 )private Integer age;Size(message 编号长度为 [4-8] , min 4, max 8)private String idNo;}其中InsertGroup和UpdateGroup只是一个普通的接口 public interface InsertGroup {}public interface UpdateGroup {}controller
package com.sofwin.validator.controller;import com.sofwin.validator.config.BaseResult;
import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.domain.UserR;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;/*** packageName: com.sofwin.validator.controller* author: wentao* date: 2023/9/4 21:14* version: 1.0* description: 请求参数校验*/RestController
RequestMapping(validator)
Validated
public class ValidatorController {PostMapping(/validPost)public BaseResult validPostTest(Valid RequestBody UserR user ) {return BaseResult.ok(user);}PostMapping(/validPost2)public BaseResult validPostTest2(Validated(InsertGroup.class) RequestBody UserR user ) {return BaseResult.ok(user);}GetMapping(/validGet1)public BaseResult validGetTest( NotBlank(message 名字不能为空) String name ) {return BaseResult.ok(name);}GetMapping(/validGet2)public BaseResult validGetTest2(Validated(InsertGroup.class) NotNull(message 名字不能为空) String name ) {return BaseResult.ok(name);}
}测试
validPost2、validGet2
validPost2 validGet2 3.6 自定义注解
当它提供的注解我们没有办法解决我们的问题的时候我们就可以自定义注解
定义注解Status
package com.sofwin.validator.config;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;/*** packageName: com.sofwin.validator.config* author: wentao* date: 2023/9/4 21:52* version: 1.0* email 1660420659qq.com* description: 自定义校验注解*/
Target({ElementType.FIELD,ElementType.PARAMETER})
Retention(RetentionPolicy.RUNTIME)
Documented
//自己写校验规则
Constraint(validatedBy {StatusConstraint.class})
//元注解 可以分组使用如果不写定义相同的注解会出现错误
Repeatable(Status.List.class)
public interface Status {String[] statusType() default {};String message() default 状态传递有误;Class?[] groups() default {};Class? extends Payload[] payload() default {};Target({ElementType.FIELD,ElementType.PARAMETER})Retention(RetentionPolicy.RUNTIME)Documentedinterface List {Status[] value();}}校验规则
package com.sofwin.validator.config;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.List;/*** packageName: com.sofwin.validator.config* author: wentao* date: 2023/9/4 22:04* version: 1.0* email 1660420659qq.com* description: 自定义校验柜子*/
public class StatusConstraint implements ConstraintValidatorStatus,Integer {ListString statusType;/*** 一般进行初始化* param constraintAnnotation*/Overridepublic void initialize(Status constraintAnnotation) {String[] strings constraintAnnotation.statusType();statusType Arrays.asList(strings);}/**** param value 参数的值* param context* return true 通过不抛出异常 fasle不通过抛出异常*/Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {if (value !null) {if (!statusType.contains(String.valueOf(value))) {return false;}return true;}return false;}
}测试
实体类
package com.sofwin.validator.domain;import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.config.Status;
import com.sofwin.validator.config.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.Mapping;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.List;/*** packageName: com.sofwin.validator.domain* author: wentao* date: 2023/9/4 21:17* version: 1.0* email 1660420659qq.com* description: 测试*/
Data
public class UserR {NotBlank(message 名称不能为空)//进行分组NotBlank(message 名称不能为空(InsertGroup),groups InsertGroup.class)private String name;NotNull(message 年龄不能为空)NotNull(message 年龄不能为空(InsertGroup),groups {InsertGroup.class,UpdateGroup.class})Range(min 1,max 200,message 最小为{min}岁最大为{max}岁 )private Integer age;Status(statusType {1,2})private Integer status;Size(message 编号长度为 [4-8] , min 4, max 8)private String idNo;}controller PostMapping(/validPost)public BaseResult validPostTest(Valid RequestBody UserR user ) {return BaseResult.ok(user);}
正常传参 非正常传参 3.7 当出现类中出现嵌套的情况
当出现嵌套的情况只需要在类的属性中在加一个注解Valid 实体类
package com.sofwin.validator.domain;import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.config.Status;
import com.sofwin.validator.config.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.Mapping;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
import java.util.List;/*** packageName: com.sofwin.validator.domain* author: wentao* date: 2023/9/4 21:17* version: 1.0* email 1660420659qq.com* description: 测试*/
Data
public class UserR {NotBlank(message 名称不能为空)//进行分组NotBlank(message 名称不能为空(InsertGroup),groups InsertGroup.class)private String name;NotNull(message 年龄不能为空)NotNull(message 年龄不能为空(InsertGroup),groups {InsertGroup.class,UpdateGroup.class})Range(min 1,max 200,message 最小为{min}岁最大为{max}岁 )private Integer age;Status(statusType {1,2})private Integer status;Size(message 编号长度为 [4-8] , min 4, max 8)private String idNo;//嵌套使用valid才能生效Validprivate ListSonUser sonUserList;
}package com.sofwin.validator.domain;import com.sofwin.validator.config.InsertGroup;
import com.sofwin.validator.config.UpdateGroup;
import lombok.Data;import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.math.BigDecimal;/*** packageName: com.sofwin.validator.domain* author: wentao* date: 2023/9/4 21:17* version: 1.0* email 1660420659qq.com* description: 测试*/
Data
public class SonUser {NotBlank(message sonName不能为空)private String sonName;}controller PostMapping(/validPost)public BaseResult validPostTest(Valid RequestBody UserR user ) {return BaseResult.ok(user);} 四、 总结
Valid没有分组的功能。
Valid可以用在方法、构造函数、方法参数和成员属性字段上
Validated提供了一个分组功能可以在入参验证时根据不同的分组采用不同的验证机制
Validated可以用在类型、方法和方法参数上。但是不能用在成员属性字段上
两者是否能用于成员属性字段上直接影响能否提供嵌套验证的功能