优雅的进行参数校验

实际项目开发中,对于请求参数校验是必不可少的,现实中很多人校验参数都是写在service中,代码极其不友好。

普通型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@PostMapping("/user/add")
public ResultVO<Long> add(@RequestBody UserDTO userDTO) {
if(StringUtils.isEmpty(userDTO.getLoginName())){
return ResultVO.failed().msg("用户名不能为空");
}
if(StringUtils.isEmpty(userDTO.getPassword())){
return ResultVO.failed().msg("密码不能为空");
}
if(StringUtils.isEmpty(userDTO.getPhone())){
return ResultVO.failed().msg("手机不能为空");
}
Long id = userService.insert(userDTO);
return ResultVO.ok().data(id);
}

每个字段都依靠if来进行判断,代码量多不说还非常不友好

优雅型

validator来帮我们实现优雅的校验参数,validator内置很多注解,如@NotNull、@NotEmpty等。

UserDTO增加验证注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Data
public class UserDTO {

/**
* 登录名
*/
@NotEmpty(message = "登录名不能为空")
private String loginName;
/**
* 登录密码
*/
@NotEmpty(message = "登录密码不能为空")
private String password;
/**
* 手机号码
*/
@NotEmpty(message = "手机号码不能为空")
private String phone;

}

Controller修改后

1
2
3
4
5
@PostMapping("/user/add")
public ResultVO<Long> add(@Validated @RequestBody UserDTO userDTO) {
Long id = userService.insert(userDTO);
return ResultVO.ok().data(id);
}

只需要在入参增加@Validated即可自动校验参数,校验不通过则会抛出异常。因此我们还需要结合统一异常捕获即可优雅的校验参数。

统一校验异常捕获

只需新建一个类打上@RestControllerAdvice注解即可自动捕获异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@RestControllerAdvice
public class ApiExceptionHandle {
/**
* 校验参数异常统一处理
*
* @param e
* @return
* @Validated @RequestBody 没有RequestBody时候抛出此异常
* https://github.com/spring-projects/spring-framework/issues/14790
*/
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultVO handleBindException(BindException e) {
log.error("参数校验异常", e);
BindingResult bindingResult = e.getBindingResult();
return ResultVO.failed().msg(bindingResult.getFieldError().getDefaultMessage());
}

/**
* 校验参数异常统一处理
*
* @param e
* @return
* @Validated @RequestBody 一起的时候抛出此异常
* https://github.com/spring-projects/spring-framework/issues/14790
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultVO handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
log.error("参数校验异常", e);
BindingResult bindingResult = e.getBindingResult();
StringBuilder stringBuilder = new StringBuilder();
for (FieldError error : bindingResult.getFieldErrors()) {
String field = error.getField();
Object value = error.getRejectedValue();
String msg = error.getDefaultMessage();
String message = String.format("错误字段:%s,错误值:%s,原因:%s;", field, value, msg);
stringBuilder.append(message).append("\r\n");
}
return ResultVO.failed().msg(stringBuilder.toString());
}
/**
* 其他异常
*
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Object handleException(HttpServletRequest request, HandlerMethod handlerMethod, Exception e) {
log.error("内部错误", e);
return ResultVO.failed().msg(ErrCodeEnum.INTERNAL_SERVER_ERROR.getMsg());

}

}

更详细的校验可参考另一篇文章:参数校验异常处理

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×