JSR303参数校验和全局异常处理
1.JSR303参数校验
1.1未使用JSR303的参数校验
- 主要是对登录表单中的密码和手机进行一个判断
@PostMapping("/doLogin")
@ResponseBody
public Result<Boolean> doLogin(LoginVo loginVo){
//日志输出
log.info(loginVo.toString());
String mobile = loginVo.getMobile();
String inputPass = loginVo.getPassword();
if (StringUtils.isEmpty(inputPass)){
return Result.error(CodeMsg.PASSWORD_EMPTY);
}
if (StringUtils.isEmpty(mobile)){
return Result.error(CodeMsg.MOBILE_EMPTY);
}
//手机格式判断
if (!ValidatorUtil.isMobile(mobile)){
return Result.error(CodeMsg.MOBILE_ERROR);
}
}
1.2JSR303参数校验
- 可以看出上面代码比较冗余,利用JSR303进行改造
一:引入依赖
<!--JSR303参数校验依赖:用于参数校验-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
二:业务代码
- 在表单上加上@Valid注解进行参数校验既可
@PostMapping("/doLogin")
@ResponseBody
//Valid用于参数校验
public Result<Boolean> doLogin(@Valid LoginVo loginVo){
//日志输出
log.info(loginVo.toString());
}
三:@Valid的实现
登录保单加上注解进行校验
@Data
public class LoginVo {
@NotNull
@MobileCheck //自定义注解,验证手机格式
private String mobile;
@NotNull
@Length(min = 6) //长度最小值为6
private String password;
}
自定义注解@MobileCheck的实现
/**
* 自定义注解用于手机格式校验
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {MobileValidator.class})
public @interface MobileCheck {
boolean required() default true ;
String message() default "手机号码格式有误!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class MobileValidator implements ConstraintValidator<MobileCheck, String> {
private boolean require = false ;
@Override
public void initialize(MobileCheck isMobile) {
require = isMobile.required() ;
}
// todo, 这里没有统一返回的格式
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if(require){
return ValidatorUtil.isMobile(value) ;
}else{
if(StringUtils.isEmpty(value)){
return true ;
}else {
return ValidatorUtil.isMobile(value) ;
}
}
}
}
2.全局异常处理
全局异常处理器
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
public Result<String> exceptionHandler(HttpServletRequest request, Exception e) {
e.printStackTrace();
//全局异常处理
if (e instanceof GlobalException){
GlobalException globalException = (GlobalException)e;
return Result.error(globalException.getCm());
} else if (e instanceof BindException) {
//绑定异常处理
BindException bindException = (BindException)e;
List<ObjectError> allErrors = bindException.getAllErrors();
ObjectError error = allErrors.get(0);
String msg = error.getDefaultMessage();
//异常信息最后附加参数信息
return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
}else {
return Result.error(CodeMsg.SERVER_ERROR);
}
}
}
全局异常
@Data
public class GlobalException extends RuntimeException {
private static final long serialVersionUID=1L;
private CodeMsg cm;
//构造方法
public GlobalException(CodeMsg cm){
super(cm.toString());
this.cm = cm;
}
}
应用:
public Boolean login(LoginVo loginVo) {
if (loginVo == null) {
//全局异常处理
throw new GlobalException(CodeMsg.SERVER_ERROR);
}
}
注:仅用于学习交流