03----------JSR303参数校验,自定义参数校验器和全局的异常处理器

一,参数校验

1,引入相关的依赖

<!-- 参数校验 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

2.在想要验证的实体前面加上@Valid

@RequestMapping("/do_login")
    @ResponseBody
    public Result<Boolean> doLogin(@Valid LoginVo loginVo){

。。。。。。

}

3.在对应的实体上加上注解

package MiaoSha.vo;

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;

import MiaoSha.validator.IsMobile;

public class LoginVo {
    
    //@isMobile自定义参数校验器
    @NotNull         //使用提供的注解
    @IsMobile      //自定义注解  这里可以加上定义的required注解,和message注解
    private String mobile;
    
    @NotNull
    @Length(min=32)
    private String password;

   get(),set()方法


   @Override
    public String toString() {
        return "LoginVo [mobile=" + mobile + ", password=" + password + "]";
    }
}
//上面如果不加上自定义注解,已经能正常判断了,如果非空,或者长度错误,会在@Valid这步就报错返回

可以加上自定义的全局异常处理器

使用自定义注解

二,自定义参数校验器

package MiaoSha.validator;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.Payload;

/**
 * 自定义IsMobile注解
 * @author msi
 *
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { IsMobileValidator.class})
public @interface IsMobile {

    boolean required() default true;//默认
    
    String message() default "手机号码格式有误";

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

    Class<? extends Payload>[] payload() default { };
    
}
上面只是定义了校验器的格式,并没有做处理

接下来进行处理

package MiaoSha.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.alibaba.druid.util.StringUtils;

import MiaoSha.util.ValidatorUtil;

class IsMobileValidator implements ConstraintValidator<IsMobile,String>{//IsMobile,String

    private boolean required=false;

 //默认值_false,用于接收注解上自定义的 required

    
    //初始化方法
    @Override
    public void initialize(IsMobile constraintAnnotation) {
        required=constraintAnnotation.required();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
    
        if(required){
            return ValidatorUtil.isMobile(value);//自定义Util,判断是否未手机号码的格式
        }else{
            if(StringUtils.isEmpty(value)){
                return true;
            }else{
                return ValidatorUtil.isMobile(value);
            }
        }
    }

}
 

统一定义异常

package MiaoSha.exception;

import MiaoSha.result.CodeMsg;

/**
 * 定义全局异常
 * @author msi
 *
 */
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 CodeMsg getCm() {
        return cm;
    }

}
 

全局异常处理器

package MiaoSha.exception;


import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import MiaoSha.result.CodeMsg;
import MiaoSha.result.Result;

@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);
        }
    }
}

使用实例

if(user==null){
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);//CodeMsg.MOBILE_NOT_EXIST未自定义的异常
        }

处理流程,

1.首先用户登录进来会触发@Valid,判断参数是否异常,异常的话会在①出抛出

2.若在处理的过程中,抛出自定义的全局异常,则会在②出抛出

其他异常,会在else中自动抛出

猜你喜欢

转载自blog.csdn.net/qq_33296156/article/details/82079107
今日推荐