谷粒商城-基础篇-DAY4-校验参数

154 阅读2分钟

一、前端校验

通过elementui的功能进行参数校验

data() {
    var fistValidator = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("首字母不能为空"));
      }else if(!/^[a-zA-Z]$/.test(value)){
        callback(new Error("首字母必须a-z或者A-Z"))
      }else{
        callback();
      } 
    };
    return {
      visible: false,
      dataForm: {
        brandId: 0,
        name: "",
        logo: "",
        descript: "",
        showStatus: "",
        firstLetter: "",
        sort: "",
      },
      dataRule: {
        name: [{ required: true, message: "品牌名不能为空", trigger: "blur" }],
        logo: [
          { required: true, message: "品牌logo地址不能为空", trigger: "blur" },
        ],
        descript: [
          { required: true, message: "介绍不能为空", trigger: "blur" },
        ],
        showStatus: [
          {
            required: true,
            message: "显示状态[0-不显示;1-显示]不能为空",
            trigger: "blur",
          },
        ],
        firstLetter: [{ validator: fistValidator, trigger: "blur" }],
        sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],
      },
    };
  },

二、后端校验-JSR303

1.给Bean添加校验住注解:javax.validation.constraints,并定义message提示
2.开启校验注解:@Valid
3.给校验的bean后紧跟BindingResult
4.分组校验

image.png

/**
 * 品牌id
 */
@NotNull(message = "修改必须指定id",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
@TableId
private Long brandId;

创建空接口

public interface AddGroup {
}

使用@Validated注解,如果不添加组,则默认都不校验

  /**
   * 保存
   */
  @RequestMapping("/save")
  public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){
brandService.save(brand);
      return R.ok();
  }

三、统一异常处理

1.使用@ControllerAdvice
2.枚举错误码
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {
    Map<String,String> map = new HashMap<>();
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleMethodException(MethodArgumentNotValidException e){
        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getFieldErrors().forEach((a)->{
            map.put(a.getField(),a.getDefaultMessage());
        });
        return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data",map);
    }
    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable){
        return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(),BizCodeEnum.VAILD_EXCEPTION.getMsg());
    }
}
public enum BizCodeEnum {
    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    VAILD_EXCEPTION(10001,"参数格式校验失败");
    private int code;
    private String msg;

    BizCodeEnum(int code,String msg){
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

四、自定义校验

1、编写一个自定义校验注解
2、编写一个自定义校验器
3、关联自定义校验器和注解

自定义校验

@Documented
@Constraint(
        validatedBy = {ListValueConstraintValidator.class}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
    String message() default "{javax.validation.constraints.NotBlank.message}";

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

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

    int[] values() default {};
}

自定义校验器

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
    private Set<Integer> set = new HashSet<>();
    //判断
    @Override
    public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
        return  (set.contains(integer));
    }
    //初始化
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] values = constraintAnnotation.values();
        for (int v:values){
            set.add(v);
        }
    }
}