SpringBoot使用@Validated注解做请求参数校验

在controller里面我们一般都要做参数检验,参数输入不正确可能导致数据不合理或者运行异常,本文主要介绍如何使用@Validated注解做请求参数的校验

目录

  • get请求和post请求
    • 在controller的类上加上@Validated注解
    • get请求参数校验
    • post请求参数校验
    • 结果说明
  • 额外内容: 优雅地处理ConstraintViolationException异常
  • GitHub项目

get请求和post请求

在controller的类上加上@Validated注解

@Validated
@RestController
@RequestMapping("/good")
public class ParasCheckController {
}

get请求参数校验

这里以使用RESTfull风格的API接口为例,下面是对goodNo参数的校验,当goodNo不为6位长度的数字时,会抛出ConstraintViolationException异常

@GetMapping("/good/{goodNo}")
public BRB good(@Pattern(regexp = "^[0-9]{6}$", message = "商品编号不正确") @PathVariable("goodNo") String goodNo) {
	log.info("TAG=good, METHOD=get, goodNo={}", goodNo);
	return new BRB(BRStatus.SUCCESS, "获取商品goodNo=" + goodNo + "信息");
}

post请求参数校验

接口如下,

@PostMapping
public BRB good(@RequestBody @Valid GoodReq goodReq, BindingResult bindingResult) {
	log.info("TAG=good, METHOD=post, goodNo={}, goodName={}, goodPrice={}", goodReq.getGoodNo(), goodReq.getGoodName(), goodReq.getGoodPrice());
	return new BRB(BRStatus.SUCCESS, "增加新商品成功");
}

GoodReq类描述了输入参数的要求,比如输入的goodNo、goodName、goodPrice都不能为空,商品编号goodNo必须为6位长度的数字字符串。如果输入参数不符合要求,则会抛出ConstraintViolationException异常

@Data
public class GoodReq {

    @NotBlank(message = "商品编号不能为空")
    @Pattern(regexp = "^[0-9]{6}$", message = "商品编号不正确")
    private String goodNo;

    @NotBlank(message = "商品名不能为空")
    @Size(max = 20, message = "商品名不能大于20")
    private String goodName;

    @NotNull(message = "商品价格不能为空")
    private Integer goodPrice;

}

结果说明

  • get请求 /good/{goodNo}
    SpringBoot使用@Validated注解做请求参数校验_第1张图片
  • post请求 /good
    SpringBoot使用@Validated注解做请求参数校验_第2张图片
    上面聊完了参数校验,如果只是想了解SpringBoot参数校验的话,到这里就结束了

额外内容: 优雅地处理ConstraintViolationException异常

@Validated注解的使用会抛出ConstraintViolationException异常,但上面截图还是正常的httpStatus 200返回,是因为对ConstraintViolationException异常做了处理

核心代码如下,更多请参考GitHub项目

  • controller的异常捕获类,捕获之后,使用resp.sendError给继承了BasicErrorController的MyErrorController做最后的包装,之后返回给前端
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandlerController {

    @ExceptionHandler(ConstraintViolationException.class)
    public void handleConstraintViolationException(HttpServletResponse resp, ConstraintViolationException ex) throws IOException {
        log.info("ConstraintViolationException");
        String msg = ex.getMessage();
        String[] msgs = msg.split(": ");
        resp.sendError(HttpStatus.OK.value(), BRStatus.PARAS_ERROR.getStatus() +  msgs[msgs.length-1]);
    }

}
@Slf4j
@Controller
public class MyErrorController extends BasicErrorController {

    @Override
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {

        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        //输出自定义的Json格式
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", status.value());
        String message = (String) body.get("message");
        if (message == null || message.equals("No message available")) {
            map.put("msg", status.getReasonPhrase());
        } else {
            if (message.startsWith(BRStatus.PARAS_ERROR.getStatus()+"")) {
                map.put("status", BRStatus.PARAS_ERROR.getStatus());
                map.put("msg", message.substring(3));
            } else {
                map.put("msg", body.get("message"));
            }
        }
        map.put("timestamp", sdf4.format(new Date()));
        return new ResponseEntity<>(map, status);
    }
    
}

GitHub项目

GitHub项目

你可能感兴趣的:(SpringBoot)