酸爽!一个基于 Spring Boot 的API、RESTful API 项目骨架,值得拥有!

SpringBoot 集成 AKKA 另外 Actor,它也是通过 actorOf() 方法创建的,所以我们也需要写生产 Actor 引用的方法,Akka 提供了 IndirectActorProducer 接口,通过实现该接口,我们就可以实现DI(依赖注入)。这使得构建分布式系统变得更加容易。您可以使用AKKA的远程Actor和集群功能来实现分布式的任务分发、数据共享和容错机制。您可以创建多个Actor来处理数据的不同部分,并使用消息传递机制进行通信和协调。每个用户可以由一个Actor表示,消息可以通过Actor之间的邮箱进行传递。 阅读详情

精选:★→2020年最新的常问企业面试题大全以及答案

来源:简单的土豆

jianshu.com/p/99fcead32d35

  • 前言

  • 特征&提供

  • 技术选型&文档


前言

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

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

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

在相关项目上线之后,我花了点时间对该种子项目做了一些精简,并且已经把该项目分享到GitHub上面了,如果你正准备做类似项目的话,可以去克隆下来试试。

项目地址&使用文档:https://github.com/lihengming/spring-boot-api-project-seed 。

如果在使用中发现问题或者有什么好建议的话欢迎提issue或pr一起来完善它。

特征&提供

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

注:使用代码生成器生成代码后会创建model、dao、service、web等包。

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

/**
 * 统一API响应结果封装
 */
public class Result {
    private int code;
    private String message;
    private Object data;
    public Result setCode(ResultCode resultCode) {
        this.code = resultCode.code;
        return this;
      }
   //省略getter、setter方法
}
/**
 * 响应码枚举,参考HTTP状态码的语义
 */
public enum ResultCode {
    SUCCESS(200),//成功
    FAIL(400),//失败
    UNAUTHORIZED(401),//未认证(签名错误)
    NOT_FOUND(404),//接口不存在
    INTERNAL_SERVER_ERROR(500);//服务器内部错误

    public int code;

    ResultCode(int code) {
        this.code = code;
    }
}
/**
 * 响应结果生成工具
 */
public class ResultGenerator {
    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";

    public static Result genSuccessResult() {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE);
    }

    public static Result genSuccessResult(Object data) {
        return new Result()
                .setCode(ResultCode.SUCCESS)
                .setMessage(DEFAULT_SUCCESS_MESSAGE)
                .setData(data);
    }

    public static Result genFailResult(String message) {
        return new Result()
                .setCode(ResultCode.FAIL)
                .setMessage(message);
    }
}

统一异常处理

  public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
        exceptionResolvers.add(new HandlerExceptionResolver() {
            public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
                Result result = new Result();
                if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误”
                    result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
                    logger.info(e.getMessage());
                } else if (e instanceof NoHandlerFoundException) {
                    result.setCode(ResultCode.NOT_FOUND).setMessage("接口 [" + request.getRequestURI() + "] 不存在");
                } else if (e instanceof ServletException) {
                    result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
                } else {
                    result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员");
                    String message;
                    if (handler instanceof HandlerMethod) {
                        HandlerMethod handlerMethod = (HandlerMethod) handler;
                        message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
                                request.getRequestURI(),
                                handlerMethod.getBean().getClass().getName(),
                                handlerMethod.getMethod().getName(),
                                e.getMessage());
                    } else {
                        message = e.getMessage();
                    }
                    logger.error(message, e);
                }
                responseResult(response, result);
                return new ModelAndView();
            }

        });
    }

常用基础方法抽象封装

public interface Service<T> {
    void save(T model);//持久化
    void save(List<T> models);//批量持久化
    void deleteById(Integer id);//通过主鍵刪除
    void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”
    void update(T model);//更新
    T findById(Integer id);//通过ID查找
    T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束
    List<T> findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4”
    List<T> findByCondition(Condition condition);//根据条件查找
    List<T> findAll();//获取所有
}

提供代码生成器来生成基础代码

public abstract class CodeGenerator {
   ...
    public static void main(String[] args) {
        genCode("输入表名");
    }
    public static void genCode(String... tableNames) {
        for (String tableName : tableNames) {
            //根据需求生成,不需要的注掉,模板有问题的话可以自己修改。
            genModelAndMapper(tableName);
            genService(tableName);
            genController(tableName);
        }
    }
  ...
}

CodeGenerator 可根据表名生成对应的Model、Mapper、MapperXML、Service、ServiceImpl、Controller(默认提供POST和RESTful两套Controller模板,根据需要在 genController(tableName)方法中自己选择,默认是纯POST的),代码模板可根据实际项目的需求来定制,以便渐少重复劳动。

由于每个公司业务都不太一样,所以只提供了一些简单的通用方法模板,主要是提供一个思路来减少重复代码的编写。在我们公司的实际使用中,其实根据业务的抽象编写了大量的代码模板。

提供简单的接口签名认证

public void addInterceptors(InterceptorRegistry registry) {
    //接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。
    if (!"dev".equals(env)) { //开发环境忽略签名认证
        registry.addInterceptor(new HandlerInterceptorAdapter() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                //验证签名
                boolean pass = validateSign(request);
                if (pass) {
                    return true;
                } else {
                    logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}",
                            request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));

                    Result result = new Result();
                    result.setCode(ResultCode.UNAUTHORIZED).setMessage("签名认证失败");
                    responseResult(response, result);
                    return false;
                }
            }
        });
    }
}
/**
 * 一个简单的签名认证,规则:
 * 1. 将请求参数按ascii码排序
 * 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
 * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
 */
private boolean validateSign(HttpServletRequest request) {
        String requestSign = request.getParameter("sign");//获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
        if (StringUtils.isEmpty(requestSign)) {
            return false;
        }
        List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
        keys.remove("sign");//排除sign参数
        Collections.sort(keys);//排序

        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串
        }
        String linkString = sb.toString();
        linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一个'&'

        String secret = "Potato";//密钥,自己修改
        String sign = DigestUtils.md5Hex(linkString + secret);//混合密钥md5

        return StringUtils.equals(sign, requestSign);//比较
}

集成MyBatis、通用Mapper插件、PageHelper分页插件,实现单表业务零SQL

使用Druid Spring Boot Starter 集成Druid数据库连接池与监控

使用FastJsonHttpMessageConverter,提高JSON序列化速度

技术选型&文档

  • Spring Boot:https://www.jianshu.com/p/1a9fd8936bd8

  • MyBatis:http://www.mybatis.org/mybatis-3/zh/index.html

  • MyBatisb通用Mapper插件:https://mapperhelper.github.io/docs/

  • MyBatis PageHelper分页插件:https://pagehelper.github.io/

  • Druid Spring Boot Starter:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter/

  • Fastjson:https://github.com/Alibaba/fastjson/wiki/%E9%A6%96%E9%A1%B5

推荐阅读

IDEA 2020,9个新特性曝光,程序员:追不上了。。。

推荐 33 个 IDEA 最牛配置,写代码太爽了

JVM 史上最最最完整深入解析(12000 字噢)

经验:一个秒杀系统的设计思考

如何在SpringBoot中异步请求和异步调用

SpringBoot+JWT+Shiro+MybatisPlus实现Restful快速开发后端脚手架


好文!必须点赞
一个基于Spring Boot的API、Restful API种子项目搭建 种子项目即是利用面向对象抽象、封装的思想,抽取项目的共同之处封装成一个种子项目。这样的话下次再开发类似的项目直接在该种子项目上迭代就行了,减少无意义的工作。 阅读详情

相关推荐

第一个 Spring Boot 应用:创建一个简单的 RESTful API!

🏆本文收录于「滚雪球学SpringBoot」专栏,手把手带你零基础入门Spring Boot,从入门到就业,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

**My Coding Family** 937

Springboot 实现api接口(一)

Springboot 实现api接口(一) 一个努力中的青蛙

hui_ss的博客 1万+

基于SpringBoot构建的种子项目+源代码+文档说明

修改application-dev.yml中的数据库配置环境 * 继承通用接口直接使用,或根据业务在基础代码上扩展 * 代码生成:在CodeGenerator的main方法中修改需要生成的表名,运行即可 ## 代码结构 ```bash ├── README.md ├── pom.xml ├── springboot-seedproject.iml ├── src │   ├── main │   │   ├── java │   │   │   └── pers │   │   │   └── hong │   │   │   └── project │ │ │ ├── SpringbootSeedprojectApplication.java 启动类 │ │ │ ├── common │ │ │ │ ├── Constants.java 常量 │ │ │ │ ├── Result.java 结果集 │ │ │ │ ├── ResultGenerator.java 响应结果生成工具 │ │ │ │ └── ServiceException.java 业务异常 │ │ │ ├── config │ │ │ │ ├── MybatisConfig.java Mybatis配置 │ │ │ │ └── WebMvcConfig.java MVC配置 │ │ │ ├── core │ │ │ │ ├── AbstractService.java service实现 │ │ │ │ ├── Mapper.java 通用mapper │ │ │ │ └── Service.java 通用service │ │ │ └── generator │ │ │ └── CodeGenerator.java 代码生成器 │ │ └── resources │ │ ├── application-dev.yml 开发环境 │ │ ├── application-pro.yml 生产环境 │ │ ├── application-test.yml 测试环境 │ │ ├── application.yml 配置文件 │ │ ├── banner.txt banner │ │ ├── mapper │ │ └── template ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

Restful风格API接口开发springMVC篇

Restful风格的API是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 在Restful风格中,用户请求的url使用同一个url而用请求方式:get,post,delete,put...等方式对请求的处理方法进行区分,这样可以在前后台分离式的开发中使得前...

weixin_30897079的博客 4872

Spring Boot种子项目,后端采用基于Java生态的Mybatis-Plus ORM和代码生成框架.zip

Spring Boot种子项目,后端采用基于Java生态的Mybatis-Plus ORM和代码生成框架

别再死记硬背了!用Python可视化带你直观理解柯西收敛定理(附NumPy代码)

本文通过Python可视化技术,结合NumPy和Matplotlib,直观展示柯西收敛定理的动态过程。文章提供了完整的代码实现,帮助读者从抽象数学定义过渡到具象理解,特别适合数学学习者和Python开发者。通过热力图和交互式参数探索,读者可以清晰观察数列收敛特性,提升数学分析的学习效率。

weixin_28465009的博客 186

基于Spring的RESTful API开发:让Web应用更加开放和灵活

Spring框架是一套开源的企业级应用程序开发框架,通过IoC(Inversion of Control)和AOP(Aspect Oriented Programming)技术,帮助开发者实现松耦合的、模块化的可重用代码。SpringMVC是Spring框架中的一个模块是一个基于MVC模式的Web框架,通过它可以方便地构建Web应用程序。摘要认证是一种在HTTP请求和响应过程中对消息进行摘要计算的认证方式。

BXA 1544

零基础搭建本地AI绘画环境:Stable Diffusion 3.5保姆级安装教程(含中文优化方案)

本文提供零基础搭建本地AI绘画环境的详细教程,重点介绍Stable Diffusion 3.5的安装与中文优化方案。从硬件配置检查到软件依赖安装,再到核心组件配置与中文语义增强,教程涵盖全流程操作指南,帮助用户快速掌握AI文生图模型的本地部署技巧,提升创作效率。

weixin_30752699的博客 314

Spring Boot 项目:构建一个简单的 RESTful API

Spring Boot 是一个用于简化 Spring 应用程序开发的框架,它通过约定优于配置的方式,让开发者更快速地构建独立的、生产级别的 Spring 应用。

ZL_dk的博客 1888

Unity-Chan Toon Shader卡通渲染学习

2.0 (UTS2)是一款用于图像和视频的卡通着色器,旨在满足从事卡通着色 3DCG 动画的创作者的需求。二、从0-1复刻UTS21.漫反射UTS2的漫反射部分主要有三个层组成,分别是基本颜色、第一阴影色和第二阴影色,分别对应着美术理论中的白、灰、黑。

qq_63133691的博客 2543

Intel Mobileye EyeQ Ultra:RISC-V架构的L4自动驾驶芯片解析

RISC-V作为开源指令集架构,凭借其模块化设计和可定制特性,正在重塑高性能计算领域。其精简指令集带来的确定性执行时序,特别适合自动驾驶等实时性要求严苛的场景。在异构计算架构中,RISC-V与专用加速器(如NPU、GPU)的协同设计,能显著提升能效比和算力密度。Mobileye EyeQ Ultra采用12核RISC-V集群,结合176TOPS AI加速器和5nm工艺,实现了L4级自动驾驶所需的实时感知与决策能力。这种架构为车载计算平台提供了可扩展的解决方案,同时降低了系统复杂度和BOM成本。

weixin_33245447的博客 428

基于Spring Boot的API、RESTful API 项目骨架

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

轻狂书生FS的博客 1844

如何在项目中集成bpmn-process-designer

文章目录一、bpmn-process-designer是什么?二、使用步骤1.将下面地址的代码下载到本地2.替换dependencies和devDependencies3.拷贝package目录4.在main.js引入代码5.拷贝src5.拷贝App.vue代码注意事项 一、bpmn-process-designer是什么? bpmn-process-designer是一个基于 bpmn.js,Vue 2.x 和 ElementUI 开发的流程设计器(前端部分),支持监听器,扩展属性,表单等配置,可自由扩展

weixin_43550766的博客 9454

Spring Boot RESTful API 开发

REST(Representational State Transfer)是一种基于资源的架构风格,强调通过 HTTP 动词(GET、POST、PUT、DELETE 等)操作资源。使用@Entity注解定义数据库表对应的实体类。return id;} }Entity;return id;} }Id;@Entity@Id。

Flying_Fish_roe的博客 1725

NX二次开发编译时dll自动数字签名及拷贝

在UG5.0开始,所有基于UG二次开发的DLL都要“签名”后才能被客户端上正版的NX调用。

菜鸟爱飞不飞的博客 2685

pynq-z2 HLS开发

定制Overlay一.用HLS生成一个定制IP功啊啊是合理的创建标题,有助于目录的生成如何改变是式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 一.用HLS生成一个定制IP ...

qq_38769280的博客 4156

你值得拥有!一个基于 Spring Boot 的API、RESTful API 的项目

点击上方蓝色字体,选择“标星公众号”优质文章,第一时间送达 关注公众号后台回复pay或mall获取实战项目资料+视频 前言特征&提供技术选型&文档前言最近使用Spring...

公众号-老炮说Java 478

MATLAB库函数unwrap(相位解卷绕)的C语言实现

什么是相位解卷绕 Q = unwrap(P) Q = unwrap(P) corrects the radian phase angles in a vector P by adding multiples of ±2π when absolute jumps between consecutive elements of P are greater than or equal to the default jump tolerance of π radians. If P is a matrix, unw

业精于勤,荒于嬉 4248

【Spring Boot】REST与RESTful详解,基于Spring Boot的RESTful API实现

提起WebAPI的开发,REST风格的API是不得不提及的一个话题。REST风格的WebAPI也是目前最流行的一种WebAPI风格,除了REST风格外,还有通过WebService或者WCF开发的基于SOAP协议的WebAPI,不过这些都在时代的潮流中或被沉淀,或又通过新的面貌重新进入我们的视野。 REST是一种基于 HTTP 协议的软件架构风格,而RESTful则是基于这种风格的实践。本文将详尽的介绍REST,并且通过Spring Boot开发RESTful WebAPI。

Arabys的博客 1153

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring Boot RESTful Web服务骨架项目指南

Spring Boot RESTful Web服务骨架项目指南 1. 项目介绍 Spring Boot Web服务骨架 是一个旨在快速启动RESTful Web服务开发的基础框架。它利用了Spring Boot的便捷性,提供了一个轻量级的起点,帮助开发者迅速搭建起具备基本结构的Web服务应用程序。本项目遵循Apache-2.0许可协议,是LEANSTACKS团队的一个解决方案,适用于那些希望以最少...

gitblog_00973的博客 749

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

使用Intellij中的Spring Initializr来快速构建Spring Boot工程 完成一个简单的RESTful API

文章目录1 Spring Boot概述2 使用IDEA中的Spring Initializr工具创建项目2.1 New => Project2.2 项目代码结构解析2.3 项目maven解析3 实现简单的RESTful功能3.1 添加web模块3.2 编写HelloWorld服务参考: 1 Spring Boot概述 本文主要目标完成Spring Boot基础项目的构建,并且实现一个简单的H...

和而不流 1988

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

一个基于Spring Boot的API、RESTful API项目骨架

点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!作者:简单的土豆www.jianshu.com/p/99fcead32d35前言最近使用Spring Boot 配合 M...

Java知音 931
上一篇: 面试被问Redis锁,我脸都绿了......
下一篇: 两小时入门 Docker(好文推荐)
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值