SpringBoot | 第八章:统一异常、数据校验处理(二)
必须非空 |
@Range |
被注释的元素必须在合适的范围内 |
创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoReq {
@NotBlank(message="code不能为空")
String code;
@Length(max=10,message="name长度不能超过10")
String name;
}
然后在控制层方法里,加入@Valid 即可,这样在访问前,会对请求参数进行检验。
@GetMapping("/demo/valid")
public String demoValid(@Valid DemoReq req) {
return req.getCode() + "," + req.getName();
}
启动,后访问http://127.0.0.1:8080/demo/valid
加上正确参数后,http://127.0.0.1:8080/demo/valid?code=3&name=s
这样数据的统一校验就完成了,对于其他注解的使用,大家可自行谷歌下,基本上都很简单的,对于已有的注解无法满足校验需要时,也可进行自定义注解的开发,一下简单讲解下,自定义注解的编写
不使用@valid的情况下,也可利用编程的方式编写一个工具类,进行实体参数校验
public class ValidatorUtil {
private static Validator validator = ((Hibernateva lidatorConfiguration) Validation
.byProvider(Hibernateva lidator.class).configure()).failFast(true).buildValidatorFactory().getValidator();
/**
* 实体校验
*
* @param obj
* @throws CommonException
*/
public static <T> void validate(T obj) throws CommonException {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj, new Class[0]);
if (constraintViolations.size() > 0) {
ConstraintViolation<T> validateInfo = (ConstraintViolation<T>) constraintViolations.iterator().next();
// validateInfo.getMessage() 校验不通过时的信息,即message对应的值
throw new CommonException("0001", validateInfo.getMessage());
}
}
}
使用
@GetMapping("/demo/valid")
public String demoValid(@Valid DemoReq req) {
//手动校验
ValidatorUtil.validate(req);
return req.getCode() + "," + req.getName();
}
自定义校验注解
自定义注解,主要时实现ConstraintValidator 的处理类即可,这里已编写一个校验常量的注解为例:参数值只能为特定的值。
自定义注解
@Documented
//指定注解的处理类
@Constraint(validatedBy = {ConstantValidatorHandler.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface Constant {
String message() default "{constraint.default.const.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String value();
}
注解处理类
public class ConstantValidatorHandler implements ConstraintValidator<Constant, String> {
private String constant;
@Override
public void initialize(Constant constraintAnnotation) {
//获取设置的字段值
this.constant = constraintAnnotation.value();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
//判断参数是否等于设置的字段值,返回结果
return constant.equals(value);
}
}
使用
@Constant(message = "verson只能为1.0",value="1.0")
String version;
运行:
此时,自定义注解已生效。大家可根据实际需求进行开发。
大家看到在校验不通过时,返回的异常信息是不友好的,此时可利用统一异常处理,对校验异常进行特殊处理,特别说明下,对于异常处理类,共有以下几种情况(被@RequestBody和@RequestParam注解的请求实体,校验异常类是不同的)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String,Object> handleBindException(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
log.info("参数校验异常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
Map<String,Object> result = new HashMap<String,Object>();
result.put("respCode" |