一个基于Spring Boot的API、Restful API种子项目搭建

文章目录

前言

参考博客一个基于Spring Boot的API、RESTful API项目种子(骨架)

最近使用Spring Boot 配合 MyBatis 、通用Mapper插件、PageHelper分页插件 连做了几个中小型API项目,做下来觉得这套框架、工具搭配起来开发这种项目确实非常舒服,团队的反响也不错。在项目搭建和开发的过程中也总结了一些小经验,与大家分享一下。

在开发一个API项目之前,搭建项目、引入依赖、配置框架这些基础活自然不用多说,通常为了加快项目的开发进度(早点回家)还需要封装一些常用的类和工具,比如统一的响应结果封装、统一的异常处理、接口签名认证、基础的增删改差方法封装、基础代码生成工具等等,有了这些项目才能开工。

然而,下次再做类似的项目上述那些步骤可能还要搞一遍,虽然通常是拿过来改改,但是还是比较浪费时间。所以,可以利用面向对象抽象、封装的思想,抽取这类项目的共同之处封装成了一个种子项目(估计大部分公司都会有很多类似的种子项目),这样的话下次再开发类似的项目直接在该种子项目上迭代就可以了,减少无意义的重复工作。

我在此基础上自个儿再DIY了一些功能,把lenosp脚手架添加进来,为了方便开发后台管理系统而不只是编写API接口。大部分应用都需要后台管理系统的支持,而有一套通用的后台管理系统模板会很方便,这里使用lenosp脚手架,大家可以进入Gitee了解该项目:Gitee/一枚码农/lenosp

因此我使用的种子项目是基于Maven多模块开发的,整体骨架使用的是lenosp的设计,在上面扩展自己额外的功能。

特征&提供

以下只对我自己新添加的一些特征、配置进行简要介绍。若要详细理解种子项目,请移步我的另外一篇博客(制作中…)

  • 最佳实践的项目结构、配置文件、精简POM

  • 统一响应结果封装及生成工具

因为要给前端返回json格式的数据,这里需要定义 统一返回码、返回结果实体类。参考博客统一返回码,返回结果实体类

  1. Result返回结果集封装
@Data
@NoArgsConstructor
public class Result<T> implements Serializable{

    private boolean success;//是否成功
    private Integer code;// 返回码
    private String message;//返回信息
    private T data;// 返回数据

    public Result(ResultCode code) {
        this.success = code.success;
        this.code = code.code;
        this.message = code.message;
    }

    public Result(ResultCode code,T data) {
        this.success = code.success;
        this.code = code.code;
        this.message = code.message;
        this.data = data;
    }

    public Result(Integer code,String message,boolean success) {
        this.code = code;
        this.message = message;
        this.success = success;
    }

    public static Result SUCCESS(){
        return new Result(ResultCode.SUCCESS);
    }

    public static Result ERROR(){
        return new Result(ResultCode.SERVER_ERROR);
    }

    public static Result FAIL(){
        return new Result(ResultCode.FAIL);
    }
}
  1. ResultCode状态码封装
public enum ResultCode {

    SUCCESS(true,10000,"操作成功!"),
    //---系统错误返回码-----
    FAIL(false,10001,"操作失败"),
    UNAUTHENTICATED(false,10002,"您还未登录"),
    UNAUTHORISE(false,10003,"权限不足"),
    SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!");

    //操作是否成功
    boolean success;
    //操作代码
    int code;
    //提示信息
    String message;

    ResultCode(boolean success,int code, String message){
        this.success = success;
        this.code = code;
        this.message = message;
    }

    public boolean success() {
        return success;
    }

    public int code() {
        return code;
    }

    public String message() {
        return message;
    }
}
  • 统一异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(UnauthorizedException.class)
    public Result handleShiroException(Exception ex) {
        return new Result(10001,"无权访问该资源",false);
    }

    @ExceptionHandler(AuthorizationException.class)
    public Result AuthorizationException(Exception ex) {
        return new Result(10001,"权限认证失败",false);
    }
    /**
     * 默认统一异常处理方法
     * @ExceptionHandler 注解用来配置需要拦截的异常类型, 也可以是自定义异常
     */
    @ExceptionHandler(Exception.class)
    public Result runtimeExceptionHandler(Exception exception, HttpServletResponse response) {
        logger.error("请求出现未知异常,异常信息为: {}", exception.getMessage());
        return new Result(10001,"请求出现未知异常,异常信息为:"+exception.getMessage(),false);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleBindException(MethodArgumentNotValidException ex) {
        /*
        // 返回所有参数效验错误信息
        StringBuilder errMsg = new StringBuilder();
        List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
        for (ObjectError allError : allErrors) {
            errMsg.append(allError.getDefaultMessage()).append(",");
        }
        return ResponseMessage.newErrorInstance(errMsg.toString());
         */
        // 只返回一条参数校验异常信息
        FieldError fieldError = ex.getBindingResult().getFieldError();
        assert fieldError != null;
        logger.info("参数校验异常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
        return new Result(10001,fieldError.getDefaultMessage(),false);
    }

    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException ex) {
        logger.info("参数校验异常:{}", ex.getMessage());
        return new Result(10001,ex.getMessage(),false);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public Result handleBindException(ConstraintViolationException ex) {
        logger.info("参数校验异常:{}", ex.getMessage());
        return new Result(10001,ex.getMessage(),false);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44950174/article/details/105464674