springboot利用JSR303进行后端校验实例

springboot利用JSR303进行后端校验

https://developer.ibm.com/zh/articles/j-lo-jsr303/参考资料

  • JSR303中,Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode , 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

  • 即可以使用注解的方式实现无侵入式的编程,当校验不通过的时候,会返回到Exception中

  • JSR303的实现方式是在bean中进行注解注入,这些注解都在javax.validation.constraints包下,也可以自行定义,需要自行定义注解、实现自定义校验器以及将注解与校验器进行关联起来

  • *** 一 ***、注解实现可以参照jsr中注解的形式,在所有的注解中,都要遵循以下的配置,即一定要有message,groups,payload三个参数,剩下的需要按需求添加;”@Constraint(validatedBy = { })“用来指定自定义校验器,需要继承ConstraintValidator类,其中A为需要关联的注解,T为bean标注自定义注解的类型,例如Integer,int等

    @NotNull注解部分信息:

@Target({
      METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = {
      })
public @interface NotNull {
     

   String message() default "{javax.validation.constraints.NotNull.message}";

   Class<?>[] groups() default {
      };

   Class<? extends Payload>[] payload() default {
      };

自定义注解

//这四个注解都要填上,最后一个注解用于指明具体实现的校验器是哪个
@Target({
      METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {
      ListValueConstraintValidator.class})
public @interface ListValue {
     
    String message() default "{com.psf.common.valid.ListValue.message}";

    Class<?>[] groups() default {
      };

    Class<? extends Payload>[] payload() default {
      };

    int[] vals() default {
     };//获取显示状态,1表示显示,0表示不显示
}

自定义校验器的实现

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
     
	//ListValue是与之需要关联的注解,即上免提到的与@ListValue注解进行绑定

    //初始化方法,可以补继承这个方法
    @Override
    public void initialize(ListValue constraintAnnotation) {
     
        //这个初始化方法的参数就是注解本身,所以我们可以获取到这个注解的信息,例如message,			//groups,payload等进行初始化
       

    }

    //判断是否校验成功。

    /**
     *
     * @param value 需要校验的值
     * @param context上下文信息
     * @return
     */
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
     
       // 这里的参数,value即是继承接口时绑定的类型,这个是用于校验的值
        //第二个参数则是上下文的信息
       
    }
}
  • 二、校验器可以实现分组校验,可以满足实现不同增删改中的问题

    • 在bean中的属性添加@ListValue(,groups={xxx.class}),groups是关联分组的表示,里面可以填一个接口作为唯一标识,例如我们可以添加一个接口作为新增的接口:AddGroup{}

      可以不做任何实现

      public interface AddGroup {
               
      }
      
    • controller的相关方法的参数中添加@Validated(value = {AddGroup.class})注解

@RequestMapping("/save")
public String save(@Validated(value = {
     AddGroup.class}) @RequestBody BrandEntity brand){
     

    brandService.save(brand);

    return "success";
}
  • 可以编写一个异常controller来统一处理校验出现的异常,需要使用上@ControllerAdvice注解

    @Slf4j
    @RestControllerAdvice(basePackages = "com.psf.gulimall.product.controller")
    //统一处理controller包下的异常
    
    public class GulimallExceptionControllerAdvice {
           
    
    
    //    @ExceptionHandler(value = Exception.class)
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public Map handleVaildException(MethodArgumentNotValidException e){
           
          log.error("数据校验出问题{},异常类型:{}",e.getMessage(),e.getClass())   ;
            //获取绑定的异常数据,即出现异常后都可以再这个类中取出
            BindingResult bindingResult = e.getBindingResult();
    
            Map<String ,String > map = new HashMap<>();
            //将绑定的数据取出放进map中
            bindingResult.getFieldErrors().forEach((item)->{
           
                map.put(item.getField(),item.getDefaultMessage());
            });
            //这里也可以直接返回Map,返回map数据
            return map;
        }
    
    
        @ExceptionHandler(value = Throwable.class)
        public R handleException(Throwable throwable ){
           
            log.error("错误",throwable);
            return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
        }
    }
    

你可能感兴趣的:(#,项目问题,springboot,java,spring)