JSR303校验

2022-10-25 15:29:55 浏览数 (1)

SpringMVC支持使用 【JSR303】 方式进行校验 1、springboot默认导第三方的校验框架hibernate-validator

使用JSR303的三大步 1)、给需要校验数据的javaBean上标注校验注解; 2)、告诉SpringBoot,这个需要校验;@Valid springmvc进入方法之前,确定参数值的时候就会进行校验,如果校验出错,直接返回错误,不执行controller代码 3)、如何感知校验成功还是失败; 只需要给开启了校验的javaBean参数后面,紧跟一个BindingResult对象就可以获取到校验结果; 只要有BindingResult,即使校验错了,方法也会执行。我们需要手动处理

统一的异常处理:

Controller:

代码语言:javascript复制
	@ApiOperation(value = "用户注册")
    @PostMapping(value = "/register")
    public Object register(@Valid @RequestBody UmsAdminParam umsAdminParam, BindingResult result) {
        Admin admin = null;

        //TODO 完成注册功能
//        int errorCount = result.getErrorCount();
//        if(errorCount>0){
//            List<FieldError> fieldErrors = result.getFieldErrors();
//            fieldErrors.forEach((fieldError)->{
//                String field = fieldError.getField();
//                log.debug("属性:{},传来的值是:{},校验出错。出错的提示消息:{}",
//                        field,fieldError.getRejectedValue(),fieldError.getDefaultMessage());
//            });
//
//
//            return new CommonResult().validateFailed(result);
//        }else {
//
//        }
        log.debug("需要注册的用户详情:{}",umsAdminParam);
        int i = 10/0;
        return new CommonResult().success(admin);
    }

利用aop完成统一的数据校验

代码语言:javascript复制
import com.xiepanpan.gmall.to.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;

/**
 * 切面如何编写
 * 1、导入切面场景
 *         <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-aop</artifactId>
 *         </dependency>
 * 2、编写切面
 *      1)、@Aspect
 *      2)、切入点表达式
 *
 *
 *      3)、通知
 *             前置通知:方法执行之前触发
 *             后置通知:方法执行之后触发
 *             返回通知:方法正常返回之后触发
 *             异常通知:方法出现异常触发
 *
 *         正常执行:   前置通知==>返回通知==>后置通知
 *         异常执行:   前置通知==>异常通知==>后置通知
 *
 *             环绕通知:4合1;拦截方法的执行
 *
 */

//利用aop完成统一的数据校验,数据校验出错就返回给前端错误提示
    @Slf4j
@Aspect
@Component
public class DataVaildAspect {

    /**
     * 目标方法的异常,一般都需要再次抛出去。让别人感知
      * @param point
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.xiepanpan.gmall.admin..*Controller.*(..))")
    public Object validAround(ProceedingJoinPoint point) throws Throwable {
        Object proceed = null;

            log.debug("校验切面介入工作....");
            Object[] args = point.getArgs();
            for (Object obj:args){
                if(obj instanceof BindingResult){
                    BindingResult r = (BindingResult) obj;
                    if(r.getErrorCount()>0){
                        //框架自动校验检测到错了
                        return new CommonResult().validateFailed(r);
                    };
                }
            }
            //就是我们反射的  method.invoke();
            proceed = point.proceed(point.getArgs());
            log.debug("校验切面将目标方法已经放行....{}",proceed);

        return proceed;
    }

}

全局拦截器:

代码语言:javascript复制
import com.xiepanpan.gmall.to.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 统一处理所有异常,给前端返回500的json
 *
 * 当我们编写环绕通知的时候,目标方法出现的异常一定要再次跑出去
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    @ExceptionHandler(value = {ArithmeticException.class})
    public Object handlerException(Exception exception){
        log.error("系统全局异常感知,信息:{}",exception.getStackTrace());
        return new CommonResult().validateFailed("数学没学好");
    }


    @ExceptionHandler(value = {NullPointerException.class})
    public Object handlerException02(Exception exception){
        log.error("系统出现异常感知,信息:{}",exception.getMessage());
        return new CommonResult().validateFailed("空指针了...");
    }


}

JavaBean:

代码语言:javascript复制
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Null;
import javax.validation.constraints.Pattern;

/**
 * 用户登录参数
 * Created by xiepanpan 4/26.
 */
@ToString
@Getter
@Setter
public class UmsAdminParam {

    /**
     * 能使用的校验注解
     * 1)、Hibernate   org.hibernate.validator.constraints 里面的所有
     * 2)、JSR303规范规定的都可;
     *      javax.validation.constraints
     *          @Pattern(regexp = "")
     */
    @Length(min = 6,max = 18,message = "用户名长度必须是6-18位")
    @ApiModelProperty(value = "用户名", required = true)
    private String username;



    @ApiModelProperty(value = "密码", required = true)
    private String password;

    @NotEmpty
    @ApiModelProperty(value = "用户头像")
    private String icon;

    @Email(message = "邮箱格式不正确,哈哈哈")
    @ApiModelProperty(value = "邮箱")
    private String email;

    //使用负责正则进行校验
    @Null  //必须是不传的
    @ApiModelProperty(value = "用户昵称")
    private String nickName;


    @ApiModelProperty(value = "备注")
    private String note;
}

通用返回对象CommonResult 类:

代码语言:javascript复制
import com.alibaba.fastjson.JSON;
import org.springframework.validation.BindingResult;

/**
 * 通用返回对象
 */
public class CommonResult {
    //操作成功
    public static final int SUCCESS = 200;
    //操作失败
    public static final int FAILED = 500;
    //参数校验失败
    public static final int VALIDATE_FAILED = 404;
    //未认证
    public static final int UNAUTHORIZED = 401;
    //未授权
    public static final int  FORBIDDEN = 403;
    private int code;
    private String message;
    private Object data;

    /**
     * 普通成功返回
     *
     * @param data 获取的数据
     */
    public CommonResult success(Object data) {
        this.code = SUCCESS;
        this.message = "操作成功";
        this.data = data;
        return this;
    }



    /**
     * 普通失败提示信息
     */
    public CommonResult failed() {
        this.code = FAILED;
        this.message = "操作失败";
        return this;
    }

    /**
     * 参数验证失败使用
     *
     * @param message 错误信息
     */
    public CommonResult validateFailed(String message) {
        this.code = VALIDATE_FAILED;
        this.message = message;
        return this;
    }

    /**
     * 未登录时使用
     *
     * @param message 错误信息
     */
    public CommonResult unauthorized(String message) {
        this.code = UNAUTHORIZED;
        this.message = "暂未登录或token已经过期";
        this.data = message;
        return this;
    }

    /**
     * 未授权时使用
     *
     * @param message 错误信息
     */
    public CommonResult forbidden(String message) {
        this.code = FORBIDDEN;
        this.message = "没有相关权限";
        this.data = message;
        return this;
    }

    /**
     * 参数验证失败使用
     * @param result 错误信息
     */
    public CommonResult validateFailed(BindingResult result) {
        validateFailed(result.getFieldError().getDefaultMessage());
        return this;
    }

    @Override
    public String toString() {

        return JSON.toJSONString(this);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

0 人点赞