JSR303校验的使用步骤
- 给Bean添加校验注解:javax.validation.contrains, 并定义自己的message提示信息
- 开启校验功能,在具体的方法参数中添加@Valid;这样校验出错是会有默认的错误响应信息
- 给校验的bean后面紧跟一个BindingResult参数, 就可以获取到校验的结果
分组校验(完成多场景的复杂校验)
1.比如添加时必须为空;修改时不能为空的字段@Null(groups={AddGroup.class}) @NotNull(groups={UpdateGroup.class}) private Long brandId;
2.给校验注解标注什么情况下进行校验
@RequestMapping("/update") public R update(@Validated(value={UpdateGroup.class}) @RequestBody BrandEntity brand){ ... }
3.注意点:
1. 实体类上没有添加groups时,如果使用了分组校验,例如`@Validated(value={AddGroup.class})`,将不会对该字段进行校验 2. 实体类上没有添加groups时,如果不添加校验分组,例如只用`@Validated`,则会对该字段进行校验
统一的异常处理
在处理校验结果是,如果再每一个处理方法中都进行一场的处理比较繁琐,我们可以使用SpringMVC为我们提供的@ControllerAdvice进行统一的异常处理
- 使用步骤
- 编写异常处理类, 并在类上添加@ControllerAdvice
- 在类中添加异常处理的方法, 并在方法上添加@ExceptionHandler
- 实例
/*集中处理所有异常*/
@Slf4j
//@ResponseBody
//@ControllerAdvice(basePackages = "com.atguigu.gulimall.product")
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product")
public class GulimallExceptionControllerAdvice {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
Map<String, String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach((item) -> {
String message = item.getDefaultMessage();
String field = item.getField();
map.put(field, message);
});
log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());
return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(), BizCodeEnum.VALID_EXCEPTION.getMsg()).put("data", map);
}
@ExceptionHandler(value = Throwable.class)
public R handleThrowable(Throwable e) {
log.error("数据校验出现问题{},异常类型:{}", e.getMessage(), e.getClass());
return R.error(BizCodeEnum.UNKNOWN_EXCEPTION.getCode(), BizCodeEnum.UNKNOWN_EXCEPTION.getMsg());
}
}
自定义的校验
1.编写一个校验注解
2.编写一个校验器 ConstrainValidator
3.关联校验注解和校验器
例子:
@ListValue(vals={0,1})
private Integer showStatus;
示例:
pom文件中添加依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
java代码如下:
package com.atguigu.common.valid;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.HashSet;
import java.util.Set;
@Documented
/*3. 将校验器和自定义注解关联*/
@Constraint(validatedBy = {ListValueConstrainValidator.class})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
/*1.自定义校验器ListValue*/
public @interface ListValue {
String message() default "{com.atguigu.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
// 有效的值
int[] vals() default {};
}
/*2.自定义的校验器, 需要实现ConstraintValidator*/
class ListValueConstrainValidator implements ConstraintValidator<ListValue, Integer> {
Set<Integer> set = new HashSet<Integer>();
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int v : vals) {
set.add(v);
}
}
//value 当前要校验的值
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
return set.contains(value);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。