springboot 使用注解优化对请求参数校验代码

111 阅读2分钟

springboot 使用注解优化对请求参数校验代码

springboot version:2.5.15
依赖:注解皆来自import javax.validation

定义全局异常

使用全局异常接收校验注解抛出的异常

// Result 为自己创建的返回类

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 忽略参数异常处理器
     *
     * @param e 忽略参数异常
     * @return Result
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
        return Result.getFail("请求参数 " + e.getParameterName() + " 不能为空");
    }

    /**
     * 缺少请求体异常处理器
     * @param e 缺少请求体异常
     * @return Result
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
        return Result.getFail("参数体不能为空");
    }

    /**
     * 参数效验异常处理器
     *
     * @param e 参数验证异常
     * @return Result
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result parameterExceptionHandler(MethodArgumentNotValidException e) {
        // 获取异常信息
        BindingResult exceptions = e.getBindingResult();
        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return Result.getFail(fieldError.getDefaultMessage());
            }
        }
        return Result.getFail("好像出错啦!");
    }
}

controller层的使用

post(❤常用)

关键注解

  • @valid
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
// 在请求body上定义注解
@Data
public class Param {
    // message 为抛出的异常信息
    // 当前版本注解验证顺序随机
    @NotNull(message = "值不能为空")
    @Size(min = 4, max = 4, message = "验证码只能为四位字符")
    private String value;
}

controller层使用 @Valid 注解使请求body的校验注解生效

import javax.validation.Valid;

@PostMapping("/test")
public Result test(@RequestBody @Valid Param param) {
    // ...
}

其他注意事项

  1. 校验注解可被继承
import javax.validation.constraints.NotNull;
// 继承上面的param,会对value和valu进行校验
@Data
public class ParamUp extends Param {
    @NotNull(message = "值不能为空")
    private String value2;
}
  1. 成员属性为类时
// 新的一个Param类,成员变量为上面的ParamUp类
public class Param {

    @NotNull(message = "name不能为空")
    private String name;

    
    // NotNull等校验注解只适用 paramUp 不能对其成员进行校验(如value2)
    @NotNull(message = "name不能为空")
    // valid 注解对value2和继承的规则校验
    @Valid
    private ParamUp paramUp;
} 

get

添加@Validated注解在类上对get请求进行校验

@RestController
@RequestMapping("/test")
@Validated
public class TestController {

  @GetMapping("checkParam")
  public String checkParam(@RequestParam  @Max(value = 99, message = "不能大于99岁") Integer age) {
    return "ok";
  }
  
  @GetMapping("checkPath/{id}")
  public String checkPath(@PathVariable  @Pattern(regexp = "^[0-9]*$", message = "id参数值必须是正整数") String id)   {
    return "ok";
  }
}

service层的使用

service类上添加@Validated注解即可

参考文献

@Validated@Valid基本了解和使用

深入了解

其他问题

完整讲解