文章目录
常用校验注解
BeanValidation中内置的
- @Null 被注释的元素必须为 null
- @NotNull 被注释的元素必须不为 null
- @AssertTrue 被注释的元素必须为 true
- @AssertFalse 被注释的元素必须为 false
- @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
- @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
- @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
- @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
- @Size(max, min) 被注释的元素的大小必须在指定的范围内
- @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
- @Past 被注释的元素必须是一个过去的日期
- @Future 被注释的元素必须是一个将来的日期
- @Pattern(value) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
- @Email 被注释的元素必须是电子邮箱地址
- @Length 被注释的字符串的大小必须在指定的范围内
- @NotEmpty 被注释的字符串的必须非空
- @Range 被注释的元素必须在合适的范围内
分组校验
分组校验的作用
- 在项目中,增删查改的四种表单的提交方式中,对表单字段的校验要求不一样,使用分组校验,可以完成,同一个字段在不同方式下,不同的校验规则。
分组校验的步骤
-
编写自定义的分组接口,接口的接口名代表分组的组名
-
注意:使用了分组校验的字段,只会在形参上的@Validate注解表明了分组,才会进行校验。举例:假如你有个字段只表明了分组校验的注解,那么在@Validate没有表明分组的情况下,是不会校验的。
-
在实体类中,用注解标注需要使用分组校验的字段以及规则
-
@Data @TableName("pms_brand") public class BrandEntity implements Serializable { private static final long serialVersionUID = 1L; /** * 品牌id */ @NotNull(message = "修改时ID不能为空",groups = {UpdateGroup.class,UpdateStatusGroup.class}) @Null(message = "增加时ID必须为空",groups = {AddGroup.class}) @TableId private Long brandId; /** * 品牌名 */ @NotBlank(message = "增加时商品名称不能为空",groups = {AddGroup.class}) private String name; /** * 品牌logo地址 */ @NotBlank(message = "增加时logo不能为空",groups = {AddGroup.class}) @URL(message = "logo必须为一个规范的URL地址",groups = {AddGroup.class, UpdateGroup.class}) private String logo; /** * 介绍 */ private String descript; /** * 显示状态[0-不显示;1-显示] */ @ListValue(val = {0,1},groups = {UpdateStatusGroup.class,AddGroup.class,UpdateGroup.class}) @NotNull(message = "增加与修改状态时不能为空",groups = {AddGroup.class, UpdateStatusGroup.class}) private Integer showStatus; /** * 检索首字母 */ @NotBlank(message = "增加时检索字母不能为空",groups = {AddGroup.class}) @Pattern(regexp = "^[a-zA-Z]$",message ="检索字母必须是a-z或A-Z",groups = {AddGroup.class, UpdateGroup.class}) private String firstLetter; /** * 排序 */ @NotNull(message = "增加时排序字段不能为空",groups = {AddGroup.class}) @Min(value = 0,message = "排序字段必须大于0",groups = {AddGroup.class, UpdateGroup.class}) private Integer sort; }
-
-
在Controller中需要校验的形参上标注@validated注解
-
public R update(@Validated(value = {UpdateGroup.class}) @RequestBody BrandEntity brand) { //brandService.updateById(brand); //brand的表若是更新了name属性,相应的CategoryBrandRelation表的name冗余字段的值也要变 brandService.updateByIdCascader(brand); return R.ok(); }
-
自定义校验注解
自定义校验注解的作用
- 当JSR303内置的注解,满足不了项目的校验要求,可以通过自定义校验注解完成参数的校验
自定义校验注解的编写步骤
-
添加依赖
<!--校验--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency> <!--高版本需要javax.el--> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.1-b08</version> </dependency>
-
编写自定义注解类
@Documented //表明该自定义注解使用的校验器是什么,这里写上了自己声明的自定义校验器 @Constraint(validatedBy = {ListValueDoubleValidator.class, ListValueIntegerValidator.class}) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) public @interface ListValue { //错误信息,必须具有的属性 //该属性去ValidationMessages.properties中取值 //这里也可以直接写上错误信息 String message() default "{com.guolei.common.valid.myvalidAnno.validAnno.ListValue}"; //分组校验,必须具有的属性 Class<?>[] groups() default { }; //自定义负载信息,必须具有的属性 Class<? extends Payload>[] payload() default { }; //数组,用户自己指定 int[] val() default {}; }
-
在对应项目的resources包下,建立ValidationMessages.properties,配置错误信息取值(这一步不是必须)
com.guolei.common.valid.myvalidAnno.validAnno.ListValue=必须提交指定的值
-
编写自定义注解类所使用的自定义校验器
public class ListValueDoubleValidator implements ConstraintValidator<ListValue,Double> { //<自定义注解类名,校验值类型> private Set<Double> set=new HashSet<>(); @Override //初始化,获得自定义注解的内容 public void initialize(ListValue constraintAnnotation) { int[] val = constraintAnnotation.val(); //在例子中这个val取出来的值是,0,1 if(val!=null){ for (double i : val) { set.add(i); } } } //覆盖验证逻辑 @Override public boolean isValid(Double dou, ConstraintValidatorContext constraintValidatorContext) { //这里写验证逻辑,通过返回true,不通过返回false //在例子中,当传来表单的字段showStatus的值不为0,1时,校验失败 return set.contains(dou); } }
-
使用实例
/** * 显示状态[0-不显示;1-显示] */ @ListValue(val = {0,1},groups = {UpdateStatusGroup.class,AddGroup.class,UpdateGroup.class}) @NotNull(message = "增加与修改状态时不能为空",groups = {AddGroup.class, UpdateStatusGroup.class}) private Integer showStatus;
SpringBoot中配置统一异常处理类
作用:统一对项目中的异常进行处理
使用步骤
-
创建一个统一异常处理类
/** *@autho GuoLei *@Description * produc微服务controller异常统一处理类 */ @Slf4j //该注解表明该异常处理类,统一处理那个包下的异常 //Rest表明该异常处理类的方法返回值以JSON数据的格式返回 @RestControllerAdvice(basePackages = "com.guolei.gulimall.product.controller") public class ContorllerExceptionHandler { //该注解表明方法处理什么类型的异常 //这里统一处理了数据的校验异常 @ExceptionHandler(value = MethodArgumentNotValidException.class) public R handleValidException(MethodArgumentNotValidException e) { BindingResult result = e.getBindingResult(); log.error("数据校验异常"); Map<String, String> resmap = new HashMap<>(); result.getFieldErrors().forEach((item) -> { resmap.put(item.getField(), item.getDefaultMessage()); }); return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMessage()) .put("data",resmap); } //最大的异常处理方法 @ExceptionHandler(value = Throwable.class) public R handleException(Throwable throwable) { return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMessage()); } }