关于java:springboot-vue前后端分离后台管理系统四

40次阅读

共计 5362 个字符,预计需要花费 14 分钟才能阅读完成。

前言

前后端拆散开发,常常用 json 数据格式进行交互,对立的响应数据格式,造成对立标准,能够大大不便前后端人员的开发。

Response 数据封装

  • 编码枚举类 ResultCode.java
public enum ResResultCode {

    /**
     * 胜利
     */
    SUCCESS(200, "ok"),

    /**
     * 申请谬误
     */
    BAD_REQUEST(400, "申请参数谬误"),

    /**
     * 未登录受权
     */
    UNAUTHORIZED(401, "有效令牌"),

    /**
     * 权限有余
     */
    FORBIDDEN(403, "权限有余"),

    /**
     * 服务器谬误
     */
    FAILED(500, "server error"),

    /**
     * 业务异样
     */
    BIZ_ERROR(600, "业务异样");

    private int status;
    private String message;

    ResResultCode(int status, String message) {
        this.status = status;
        this.message = message;
    }

    public int getStatus() {return status;}

    public String getMessage() {return message;}

    public void setStatus(int status) {this.status = status;}

    public void setMessage(String message) {this.message = message;}
}
  • json 数据封装类
@Data
public class ResResult {

    /**
     * 响应编码
     */
    private int code;
    /**
     * 响应信息
     */
    private String msg;
    /**
     * 响应数据
     */
    private Object data;

    public ResResult(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public ResResult(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static ResResult success() {return new ResResult(ResResultCode.SUCCESS.getStatus(), ResResultCode.SUCCESS.getMessage(), null);
    }

    public static ResResult success(Object data) {return new ResResult(ResResultCode.SUCCESS.getStatus(), ResResultCode.SUCCESS.getMessage(), data);
    }

    public static ResResult failure() {return new ResResult(ResResultCode.FAILED.getStatus(), ResResultCode.FAILED.getMessage());
    }

    public static ResResult failure(ResResultCode ResResultCode) {return new ResResult(ResResultCode.getStatus(), ResResultCode.getMessage());
    }

}

自定义异样类

  • BizErrorException.java 用来抛出业务异样
public class BizErrorException extends RuntimeException {

    private ResResultCode resResultCode;
    private String message;

    public BizErrorException(ResResultCode resResultCode) {this.resResultCode = resResultCode;}

    public BizErrorException(ResResultCode resResultCode, String message) {
        this.resResultCode = resResultCode;
        this.message = message;
    }

    public ResResultCode getResResultCode() {return resResultCode;}

    @Override
    public String getMessage() {return message;}

    public void setMessage(String message) {this.message = message;}
}
  • BadRequestException.java 用来抛出申请参数异样
public class BadRequestException extends RuntimeException {public BadRequestException() { }

    public BadRequestException(String message) {super(message);
    }
}

全局申请参数校验

尽管 spring 提供了 @Valid 能够进行申请参数的校验

留神一个坑:hibernate-validator 在 springboot 2.3 之后就须要手动引入了,不再主动配置。

<!-- springboot 2.3 之后隐没的 hibernate-validator 解决办法 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

作为一个前后端拆散我的项目,并且接口并不对外裸露,后端每个接口调用都创立一个 vo 类,显然是十分麻烦的,这边就不必这种形式

这里就抉择了一个偷懒的办法,就是 利用 Knife4j 动静申请参数 再加上 AOP 进行校验。具体实现步骤:

  1. 引入 AOP 依赖
<!-- AOP -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  1. 新建一个 aop 类 ReqValidateAop.java

在执行每个 @DynamicParameters 注解润饰的接口是进行校验,对每个 required = true 的参数进行校验。

/**
 * 对含有 @DynamicParameters 动静参数的接口 进行申请参数校验
 */
@Aspect
@Component
@Slf4j
public class ReqValidateAop {

    /**
     * 所有办法:@Pointcut("execution(* com.ify.formwork.web.controller.*.*.*(..))")
     * 含有 @DynamicParameters 注解:@Pointcut("@annotation(com.github.xiaoymin.knife4j.annotations.DynamicParameters)")
     */
    @Pointcut("@annotation(com.github.xiaoymin.knife4j.annotations.DynamicParameters)")
    public void paramValidate() {}

    @Before("paramValidate()")
    public void before(JoinPoint joinPoint) throws BadRequestException {List<String> errList = new ArrayList<>();
        Object[] objects = joinPoint.getArgs();
        JSONObject param = (JSONObject) objects[0];
        // 获取以后办法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 获取办法 @DynamicParameters properties
        DynamicParameters annotation = method.getAnnotation(DynamicParameters.class);
        List<DynamicParameter> list = Arrays.asList(annotation.properties());
        for (DynamicParameter dynamicParameter : list) {
            // 必传参数校验
            if (dynamicParameter.required()) {Object o = param.get(dynamicParameter.name());
                // 申请参数为 null 或申请参数为字符串为空串
                boolean badRequest = (null == o) || (o instanceof String && StrUtil.isEmpty((String) o));
                if (badRequest) {errList.add(dynamicParameter.name() + "不能为空");
                }
            }
        }
        if (!errList.isEmpty()) {throw new BadRequestException(StrUtil.join(",", errList));
        }
    }
}

全局异样拦挡解决

对服务抛出的异样进行接管,对立解决返回给前端

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /***
     * 性能形容:  捕捉申请参数异样 ReqValidateAop.java 自定义校验形式
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BadRequestException.class)
    public ResResult handleBadRequestException(BadRequestException e) {return new ResResult(ResResultCode.BAD_REQUEST.getStatus(), e.getMessage());
    }

    /**
     * 性能形容:  捕捉申请参数异样 @valid 校验参数形式 (如果采纳这种形式的话能够进行应用)
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResResult handleBadRequestException(MethodArgumentNotValidException e) {BindingResult bindingResult = e.getBindingResult();
        List<String> errors = new ArrayList<>();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {errors.add(fieldError.getField() + fieldError.getDefaultMessage());
        }
        return new ResResult(ResResultCode.BAD_REQUEST.getStatus(), StrUtil.join("|", errors));
    }

    /**
     * 业务异样捕捉 对立返回 500 状态,具体信息封装在 msg 里
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(BizErrorException.class)
    public ResResult handleBizErrorException(BizErrorException e) {if (StrUtil.isNotEmpty(e.getMessage())) {e.getResResultCode().setMessage(e.getMessage());
        }
        return ResResult.failure(e.getResResultCode());
    }

    /**
     * 性能形容: 异样对立返回, 对立返回 500 状态
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ResResult handleException(Exception e) {log.error("server error = {}", e.getMessage());
        return ResResult.failure();}
}

后端的对立数据封装差不多就这样了。。。

正文完
 0