一般代码的controller层都是处理前端请求的,参数有实体bean还有单个参数,目前我的代码里只涉及这两块,这时候就要有参数校验,不然该进来的没进来,不该进的都进来了很是烦。
单个参数校验:
一般情况用的是@NotNull这个注解,比较通用,我这边String的参数用的是@NotBlank,int的参数用的是@NotEmpty。具体区别就不细说了。贴段controller代码
/**
* 参数校验测试
* @return
*/
@Operation(summary = "单个参数校验测试", description = "参数校验测试")
@@GetMapping("/dctest")
public CodeMsg dctest(@NotEmpty(message="applyId不能为空") int applyId,@NotBlank(message="beginTime不能为空") String
beginTime,@NotBlank(message="endTime不能为空") String endTime) {
return CodeMsg.SUCCESS;
}
三个参数建议把参数变成对象校验,代码是方法片段,类上面还要添加@Validated注解,不然校验不生效,如:
@Api(tags = "testController")
@RestController
@Validated
public class apiController{}
再新建一个全局异常捕获类
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ValidationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<StringBuffer> handle(ValidationException exception) {
StringBuffer msg = new StringBuffer();
if(exception instanceof ConstraintViolationException){
ConstraintViolationException exs = (ConstraintViolationException) exception;
Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
for (ConstraintViolation<?> item : violations) {
msg.append(item.getMessage()+"!");
}
}
log.error("ValidationException:"+msg.toString());
return Result.error(CodeMsg.BIND_ERROR,msg);
}
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<StringBuffer> handle(BindException exception) {
StringBuffer msg = new StringBuffer();
if(exception instanceof BindException){
BindException exs = (BindException) exception;
BindingResult br = exs.getBindingResult();
for(ObjectError err:br.getAllErrors()) {
msg.append(err.getDefaultMessage()+"!");
}
}
log.error("BindException:"+msg.toString());
return Result.error(CodeMsg.BIND_ERROR,msg);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<StringBuffer> handle(MethodArgumentNotValidException exception) {
StringBuffer msg = new StringBuffer();
if(exception instanceof MethodArgumentNotValidException){
MethodArgumentNotValidException exs = (MethodArgumentNotValidException) exception;
BindingResult br = exs.getBindingResult();
for(ObjectError err:br.getAllErrors()) {
msg.append(err.getDefaultMessage()+"!");
}
}
log.error("MethodArgumentNotValidException:"+msg.toString());
return Result.error(CodeMsg.BIND_ERROR,msg);
}
}
我这边调试的时候单个参数报错一般是前两个,ValidationException和BindException,对象参数校验一般报的是MethodArgumentNotValidException这个。具体取参数报错就是用msg来组装错误信息,这里错误信息都是写在注解的message里的,因为如果不写就拿不到具体是哪个参数报的错,需要我们自己手动补全,不写message的情况,就只能显示:不能为空,什么不为空它不会返回。这里只做取报错信息的值,其他什么返回code不做细说了。
对于对象的参数校验同理
@NotBlank(message="carId不能为空")
private String carId;
@NotBlank(message="beginTime不能为空")
private String beginTime;
@NotBlank(message="endTime不能为空")
private String endTime;
controller有所不同
/**
* 参数校验测试
* @return
*/
@Operation(summary = "对象参数校验测试", description = "参数校验测试")
@PostMapping("/dctest")
public CodeMsg dctest(@RequestBody @Valid testParam testparam ) {
return CodeMsg.SUCCESS;
}
对象的前面要加@Valid注解,其他都是一样的了。具体的可以自己试试