JSR303参数校验和全局异常处理

开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空,非null,整数值的范围,字符串的个数,日期,邮箱等等。最常见的就是我们直接写代码校验,这样以后比较繁琐,而且不够灵活。故引出使用JSR303来做参数校验。参数校验的实现:

  • 手机号和密码字段自定义注解

  • 为了让客户端显示更加友好

  • 需要自定义异常拦截器

1. 添加依赖

1
2
3
4
5
6
<!--JSR303参数检验+全局异常处理器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.0.6.RELEASE</version>
</dependency>

2.在需要验证的类前加@Valid并在该类内需要参数检查的成员上加自定义注解

1
2
3
4
5
6
7
8
9
10
11
@Controller
@RequestMapping("/login")
public class LoginController {
@RequestMapping("/do_login")
@ResponseBody
public Result<String> doLogin(HttpServletResponse response,
@Valid LoginVo loginVo){

logger.info(loginVo.toString());
}
}
1
2
3
4
5
6
7
8
9
10
@Data
public class LoginVo {
@NotNull
@IsMobile
private String mobile;
@NotNull
@Length(min = 32)
private String password;

}

3. IsMobile注解的编写[可参考@NotNull]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})

@Retention(RetentionPolicy.RUNTIME)

@Documented
@Constraint(
validatedBy = {IsMobileValidator.class}
)
public @interface IsMobile {
boolean required() default true;
String message() default "电话号码格式错误";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

4.指定校验器的实现[IsMobileValidator.class]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class IsMobileValidator implements ConstraintValidator<IsMobile,String> {

private boolean required = false;
@Override
//初始化方法拿到注解,可以定义一个字符为空
public void initialize(IsMobile constraintAnnotation) {
constraintAnnotation.required();
}

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
//值是必须的
if(required){
return ValidatorUtil.isMobile(value);
}else{
if(StringUtils.isEmpty(value)){
return true;
}else{
return ValidatorUtil.isMobile(value);
}
}
}
}

5.自定义异常拦截器

当校验不通过时,会抛出异常。这时如果没有定义全局异常处理器进行处理(对异常进行封装和返回)。则会发生400错误(即只有请求的发起,却没有收到正常的响应(response),因为还没有来得及return就抛出了异常(这种异常没有被处理))。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ControllerAdvice

@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result<String> exceptionHandler(HttpServletRequest request,Exception e){
e.printStackTrace();
if(e instanceof GlobalException) {
GlobalException ex = (GlobalException) e;
return Result.Error(ex.getCm());
}else if(e instanceof BindException){
BindException ex = (BindException) e;
List<ObjectError> errors = ex.getAllErrors();
//为了方便起见,只取第一个错误

ObjectError error = errors.get(0);
String msg = error.getDefaultMessage();
return Result.Error(CodeMsg.BIND_ERROR.fillArgs(msg));
}else{
return Result.Error(CodeMsg.SERVER_ERROR);
}
}
}
文章目录
  1. 1. 1. 添加依赖
  2. 2. 2.在需要验证的类前加@Valid并在该类内需要参数检查的成员上加自定义注解
  3. 3. 3. IsMobile注解的编写[可参考@NotNull]
  4. 4. 4.指定校验器的实现[IsMobileValidator.class]
  5. 5. 5.自定义异常拦截器
| 139.6k