1、请求体中校验所有字段,并统一返回
- 引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 异常拦截处理
@Slf4j
//@ControllerAdvice 配合 @ExceptionHandler 实现全局异常处理,会拦截所有的controller,controller如果抛校验异常这个地方会拦截到
@RestControllerAdvice// 这个包名就是我们要直接捕获那个包里面得异常信息,如果包名不写,那么就捕获所有异常信息
public class JsrExceptionControllerAdvice {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public AjaxResult handleValidException(MethodArgumentNotValidException e) {
log.error("数据校验出现问题:{}, 异常类型:{}", e.getMessage(), e.getClass());
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);
});
return AjaxResult.error("data", map);
}
}
- 测试方法
@PostMapping("/query")
@ApiOperation(value = "查询信息")
public AjaxResult<TradeInfoVO> query(@RequestBody @Validated TradeInfoRequest tradeInfoRequest, HttpServletRequest request) {
}
@Data
public class TradeInfoRequest implements Serializable {
@ApiModelProperty("名称")
@NotBlank(message ="名称不能为空")
private String name;
@ApiModelProperty("id")
@NotNull(message = "id不能为空")
private Long id;
}
- 结果
{
"success": false,
"code": 500,
"msg": "data",
"data": {
"name": "名称不能为空",
"id": "id不能为空"
}
}
2、若果是List 请求体怎校验参数
- 测试方法
@RestController
@Validated
public class ApiController extends BaseController
{
@PostMapping("/addInfo")
@ApiOperation(value = "添加信息")
public AjaxResult addTradeInfo(@RequestBody @Valid List<TradeAddInfoRequest> tradeAddInfoRequest, HttpServletRequest request) {
}
}
- 返回结果
{
"success": false,
"code": 500,
"msg": "addTradeInfo.tradeAddInfoRequest[1].amount: 金额不能为空, addTradeInfo.tradeAddInfoRequest[0].name: 名称不能为空",
"data": null
}
3、自定义注释
- 根据@NotNull进行改写
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
// 1、验证器,这个需要自定一个类实现ConstraintValidator接口
validatedBy = {ArraySatusHandler.class}
)
public @interface ArrayStatus {
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
//2、 默认值,注解上填写的值
int [] value() default {};
}
//实现的接口,可以直接看 validatedBy = {},将validatedBy 点击进去 是一个接口interface ConstraintValidator<A extends Annotation, T> Annotation是注解,T 前端给注解的属性传值的类型
public class ArraySatusHandler implements ConstraintValidator<ArrayStatus, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ArrayStatus constraintAnnotation) {
//获取注解中的值,默认填写的值,注解上写的value = {1,2},那么set中就是1,2
int[] value = constraintAnnotation.value();
for (int i : value) {
set.add(i);
}
}
@Override
public boolean isValid(Integer o, ConstraintValidatorContext constraintValidatorContext) {
//o 就是前端传送过来的值,进行和set中的值进行比较
if (set.contains(o)) {
return true;
}
return false;
}
}
@ArrayStatus(value = {1,2}, message = "值必须为1或2")
private Integer userId;
- 结果