基于SpringBoot的JSR303参数校验

JSR303验证

  1. 导入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  1. 设置分组接口
public interface UpdateGroup {
}

public interface AddGroup {
}
  1. 修改实体类(使用lombok自动生成方法)
@Data
public class BrandEntity implements Serializable {
   private static final long serialVersionUID = 1L;

   /**
    * 品牌id
    */
   @Null(groups = AddGroup.class,message = "新增不能指定id")  //必须为空校验
   @NotNull(groups = UpdateGroup.class,message = "更新请指定id")  //不能为空校验
   @TableId
   private Long brandId;
   /**
    * 品牌名
    */
   @NotBlank(message = "品牌名字不能为空",groups = AddGroup.class)
   private String name;
   /**
    * 品牌logo地址
    */
   @NotBlank(groups = AddGroup.class)
   @URL(message = "URL格式不合法",groups = {AddGroup.class,UpdateGroup.class})  //URL校验
   private String logo;
   /**
    * 介绍
    */
   @NotBlank(message = "介绍不能为空",groups = AddGroup.class)
   private String descript;
   /**
    * 显示状态[0-不显示;1-显示]
    */
   @NotNull(groups = AddGroup.class)
   @ListValue(list = {0,1},groups = {AddGroup.class,UpdateGroup.class},message = "必须提交指定的值")     //自定义校验
   private Integer showStatus;
   /**
    * 检索首字母
    */
   @NotBlank(groups = {AddGroup.class})
   @Pattern(regexp = "^[a-zA-Z]$",message = "检索必须是一个A-Z的首字母",groups = {AddGroup.class,UpdateGroup.class})   //表示属于哪几个分组
   private String firstLetter;
   /**
    * 排序
    */
   @NotNull(groups = {AddGroup.class})
   @Min(value = 0,groups = {AddGroup.class,UpdateGroup.class}) //最小值校验
   private Integer sort;
}
  1. 控制器校验
@RequestMapping("/save")
  //@RequiresPermissions("product:brand:save")
  public R save(@Validated(value = AddGroup.class) @RequestBody BrandEntity brand/*, BindingResult result*/){
     /* if (result.hasErrors()){
          Map<String,String> resp = new HashMap<>();    //手动处理错误
          result.getFieldErrors().forEach(e->{
              resp.put(e.getField(),e.getDefaultMessage());
          });
          return R.error().put("data",resp);
      }*/
    brandService.save(brand);


      return R.ok();
  }
  1. 通用异常处理
@RestControllerAdvice
public class GuliMallExceptionHandler {
    /**
     * 处理参数异常,控制器参数校验不过会抛出异常,被拦截到,然后统一异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R methodArgumentNotValidExceptionHandle(MethodArgumentNotValidException e){
        BindingResult result = e.getBindingResult();
        Map<String,String> resp = new HashMap<>();
        result.getFieldErrors().forEach(error -> {
            resp.put(error.getField(),error.getDefaultMessage());
        });
        return R.error(BizCode.VALID_EXCEPTION).put("data",resp);
    }


    /**
     * 通用异常返回
     * @param exception
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R exceptionHandle(Exception exception){
        exception.printStackTrace();
        return R.error(BizCode.UNKNOW_EXCEPTION).put("data",exception);
    }
}
  1. 返回结果类
public class R extends HashMap<String, Object> {
   private static final long serialVersionUID = 1L;
   
   public R() {
      put("code", 0);
      put("msg", "success");
   }
   
   public static R error() {
      return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
   }


   public static R error(BizCode bizCode){
      return error(bizCode.getCode(),bizCode.getMsg());
   }

   public static R error(String msg) {
      return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
   }
   
   public static R error(int code, String msg) {
      R r = new R();
      r.put("code", code);
      r.put("msg", msg);
      return r;
   }

   public static R ok(String msg) {
      R r = new R();
      r.put("msg", msg);
      return r;
   }
   
   public static R ok(Map<String, Object> map) {
      R r = new R();
      r.putAll(map);
      return r;
   }
   
   public static R ok() {
      return new R();
   }


   public R put(String key, Object value) {
      super.put(key, value);
      return this;
   }
}
  1. 业务异常代码
@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum  BizCode {

    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    VALID_EXCEPTION(10001,"参数校验失败");

    private Integer code;
    private String msg;
}

-----------------------------自定义校验-----------------------------

  • 注解
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })   //具体实现类
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {

    String message() default "{com.example.common.valid.ListValue.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    int[] list() default { };   //校验的类型

}
  • 校验方法
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {   //继承接口,表明数据类型

    private  static final Set<Integer> values = new HashSet<>();
    /**
     * 初始化方法,将指定的数据填充进set
     * @param constraintAnnotation
     */
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] arr = constraintAnnotation.list();
        Arrays.stream(arr).forEach(values::add);
    }

    /**
     * 判断是否校验成功
     * @param integer
     * @param constraintValidatorContext
     * @return
     */
    @Override
    public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
        return values.contains(integer);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值