# 版本

2.5.2

# 依赖

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'

# 全局异常配置

@ControllerAdvice
public class ExceptionHandlerAdvice {
    /**
     * 全局异常兜底处理
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ApiData<Void> handleException(Exception e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        apiData.setMsg(e.getMessage());
        return apiData;
    }
    /**
     * 业务异常消息
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public ApiData<Void> handleException(ServiceException e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(e.getStatusCode());
        apiData.setMsg(e.getMessage());
        return apiData;
    }
    /**
     * [@RequestParam] 注解的参数不存在
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public ApiData<Void> handleException(MissingServletRequestParameterException e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        apiData.setMsg(MessageFormat.format("缺少参数{0},类型[{1}]", e.getParameterName(), e.getParameterType()));
        return apiData;
    }
    /**
     * [POST/GET] 单参数验证未通过,必须在 Controller 类上加上 @Validated 注解,否则在参数上无效
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ApiData<Void> handleException(ConstraintViolationException e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        apiData.setMsg(e.getMessage());
        return apiData;
    }
    /**
     * [GET] 对象参数验证未通过
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public ApiData<Void> handleException(BindException e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        apiData.setMsg(parseErrors(e.getBindingResult()).toString());
        return apiData;
    }
    /**
     * [POST] 对象参数验证未通过
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiData<Void> handleException(MethodArgumentNotValidException e) {
        ApiData<Void> apiData = new ApiData<>();
        apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        apiData.setMsg(parseErrors(e.getBindingResult()).toString());
        return apiData;
    }
    private Map<String, String> parseErrors(BindingResult bindingResult) {
        return bindingResult.getAllErrors().stream().collect(Collectors.toMap(objectError -> ((FieldError) objectError).getField(), objectError -> {
            if (objectError.getDefaultMessage() != null) {
                return objectError.getDefaultMessage();
            } else {
                return "参数校验失败";
            }
        }));
    }
}

# 使用

# 单参数验证
/**
 * 必须在 Controller 类上加上 @Validated 注解,加在参数上无效
 */
@RequestMapping("validate")
public void validate(@RequestParam @Min(10) Long id) {
    System.out.println(id);
}

如果参数不加 @RequestParam 注解,前端请求未携带 id 的话,会打印出 null ,携带 id 的话,会校验参数是否符合条件(会触发 ConstraintViolationException ),但是如果加了 @NotNull 注解的话,也能拦截到为 null 的情况,会触发 ConstraintViolationException 。如果参数加了 @RequestParam 注解的话,前端请求未携带 id 的话,会触发 MissingServletRequestParameterException@Validated 注解必须要加在 Controller 类上,否则校验无效。

# POST 对象
/**
 * 必须在参数上加上注解 @Validated,类上的无效
 */
@PostMapping("validatePost")
public void validatePost(@RequestBody @Validated Parameter parameter) {
    System.out.println(parameter.toString());
}

@Validated 注解必须要加在参数上,否则即使 Controller 类上加了也无效。 @RequestBody 注解,加了的话, MethodArgumentNotValidException 会获取到所有属性的校验错误信息,未加的话,会触发 BindException ,只会知道第一个未满足校验条件的属性报错信息。

# GET 对象
/**
 * 必须在参数上加上注解 @Validated,类上的无效
 */
@GetMapping("validateGet")
public void validateGet(@Validated Parameter parameter) {
    System.out.println(parameter);
}

@Validated 注解必须要加在参数上,否则即使 Controller 类上加了也无效。

# 待补充

分组校验的内容 Spring Boot 参数校验以及分组校验的使用

# 总结

  • 单参数加 @RequestParam@Validated 加在类上
  • POST 对象加 @RequestBody@Validated 加在参数上
  • GET 对象不加 @RequestBody@Validated 加在参数上
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

ICUXIKA 微信支付

微信支付

ICUXIKA 支付宝

支付宝

ICUXIKA 贝宝

贝宝