目录
VO 声明验证
在 VO 中使用 javax.validation.constraints 包提供的验证注解:
@Data
public class AnchorRecordVO {
@NotNull(message = "基站编号不能为空")
private Long num;
@NotNull(message = "天线编号不能为空")
private Integer antId;
private String site;
...
}
Controller 中使用 @Validated
在请求参数前使用 @Valid 注解就可以完成验证,验证结果将存放到 BindingResult 中。
@RequestMapping(value = "/anchors", method = RequestMethod.POST)
@ResponseBody
public ResultBean addAnchor(@RequestBody @ValidatedAnchorRecordVO vo, BindingResult bindingResult) {
return new ResultBean(anchorService.save(vo));
}
使用 ControllerAdvice 统一处理
定义一个异常处理, 使用 @ResponseBody 注解才能返回自定义格式,否则Spring 将包装一个返回结果,并且 HTTP Status 为400
@ControllerAdvice
@Slf4j
public class ControllerExceptionHandler {
/**
* 处理验证异常
*
* @param request
* @param exception
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultBean handleBindException(HttpServletRequest request, MethodArgumentNotValidException exception) {
log.error("访问" + request.getRequestURI() + "发生参数验证异常", exception);
ResultBean<?> result = new ResultBean();
String messages = exception.getBindingResult().getAllErrors()
.stream()
.map(ObjectError::getDefaultMessage)
.reduce((m1, m2) -> m1 + "," + m2)
.orElse("参数输入有误");
result.setMsg(messages);
result.setCode(FAIL);
return result;
}
/**
* 处理参数类型转换异常
*
* @param request
* @param exception
* @return
*/
@ExceptionHandler(InvalidFormatException.class)
@ResponseBody
public ResultBean handleParseException(HttpServletRequest request, InvalidFormatException exception) {
String messages = String.format("字段 [%s] 的值 [%s] 不能转换成 [%s] 类型", exception.getPathReference(),
exception.getValue(), exception.getTargetType().getName());
log.error("访问" + request.getRequestURI() + "发生参数验证异常 : {}", messages);
ResultBean<?> result = new ResultBean();
result.setMsg("参数类型输入有误");
result.setCode(FAIL);
return result;
}
}
类库说明
1. 注解说明
| 验证注解 | 验证的数据类型 | 说明 |
|---|---|---|
| @AssertFalse | Boolean,boolean | 验证注解的元素值是false |
| @AssertTrue | Boolean,boolean | 验证注解的元素值是true |
| @NotNull | 任意类型 | 验证注解的元素值不是null |
| @Null | 任意类型 | 验证注解的元素值是null |
| @Min(value=值) | BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型 | 验证注解的元素值大于等于@Min指定的value值 |
| @Max(value=值) | 和@Min要求一样 | 验证注解的元素值小于等于@Max指定的value值 |
| @DecimalMin(value=值) | 和@Min要求一样 | 验证注解的元素值大于等于@ DecimalMin指定的value值 |
| @DecimalMax(value=值) | 和@Min要求一样 | 验证注解的元素值小于等于@ DecimalMax指定的value值 |
| @Digits(integer=整数位数, fraction=小数位数) | 和@Min要求一样 | 验证注解的元素值的整数位数和小数位数上限 |
| @Size(min=下限, max=上限) | 字符串、Collection、Map、数组等 | 验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小 |
| @Past | java.util.Date,java.util.Calendar;Joda Time类库的日期类型 | 验证注解的元素值(日期类型)比当前时间早 |
| @Future | 与@Past要求一样 | 验证注解的元素值(日期类型)比当前时间晚 |
| @NotBlank | CharSequence子类型 | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首位空格 |
| @Length(min=下限, max=上限) | CharSequence子类型 | 验证注解的元素值长度在min和max区间内 |
| @NotEmpty | CharSequence子类型、Collection、Map、数组 | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
| @Range(min=最小值, max=最大值) | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型 | 验证注解的元素值在最小值和最大值之间 |
| @Email(regexp=正则表达式,flag=标志的模式) | CharSequence子类型(如String) | 验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式 |
| @Pattern(regexp=正则表达式,flag=标志的模式) | String,任何CharSequence的子类型 | 验证注解的元素值与指定的正则表达式匹配 |
| @Valid | 任何非原子类型 | 指定递归验证关联的对象如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证 |
2. 使用groups的校验
同一个对象要复用,但在不同场景下要求实效不同的校验规则, 如 ID 字段,在新增时不需要验证, 但在更新接口中要求不能为空。
2.1 先定义groups的分组接口
import javax.validation.groups.Default;
public interface Create extends Default {
}
import javax.validation.groups.Default;
public interface Update extends Default{
}
2.2 在验证类校验注解中使用
@NotNull(message = "id不能为空", groups = Update.class)
private Long userId;
2.3 Controller 中设置 Groups
public ResultBean update(@RequestBody @Validated(Update.class) UserVo userVo){
}
3. 在Controller接口中直接使用
3.1 接口方法中使用验证注解
public ResultBean getUser(@RequestParam("userId") @NotNull(message = "用户id不能为空") Long userId) {
3.2 Controller 中开启验证
@RestController
@RequestMapping("user/")
@Validated
public class UserController{ ... }
版权声明:本文为weixin_39340061原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。