> 技术文档 > 前后端分离博客 Weblog 项目实战(环境搭建)_犬小哈实战专栏

前后端分离博客 Weblog 项目实战(环境搭建)_犬小哈实战专栏

前后端分离博客 Weblog 项目实战:专栏介绍 - 犬小哈专栏     原文作者

http://116.62.199.48/

功能模块

技术栈

必备环境

后端环境:

  • JDK 1.8 版本(此版本是目前企业中使用最广泛的);
  • MySQL 5.7 版本 (或者 8.x 版本都可以,本项目使用的是 5.7 版本);
  • Maven 3.8 版本 (项目构建工具);

前端环境:

安装 Node.js 环境

安装开发工具 VSCode

安装各种插件,来加快开发任务

springboot后端过程搭建

1. 搭建 Spring Boot 多模块工程(通过 Spring Initializr)

什么是多模块项目?

多模块项目是项目构建中的概念。拿 Maven 来说,多模块项目(Multi-Module Project)是其一个重要特性,它允许我们在一个项目中管理多个子模块。

在一个 Maven 多模块项目中,每个模块都是一个独立的项目,拥有自己的 POM 文件(Project Object Model,项目对象模型)。这些模块可以互相依赖,也可以被其他项目依赖。但是,所有的模块都会被统一管理,它们共享同一套构建系统和依赖管理。

Maven 多模块项目的结构大概是下面这样的:

my-app/ (父项目) |- pom.xml |- my-module1/ (子模块1) | |- pom.xml |- my-module2/ (子模块2) |- pom.xml | ... (实际企业级项目中,会分非常多的模块) 

在这个例子中,my-app 是父项目,my-module1 和 my-module2 是它的子模块。每个模块都有自己的 pom.xml 文件。

为什么需要多模块项目?

主要有以下几个原因:

  • 代码组织:在大型项目中,我们经常需要把代码分成多个模块,以便更好地组织代码。每个模块可以聚焦于一个特定的功能或领域,这样可以提高代码的可读性和可维护性。

  • 依赖管理:Maven 多模块项目可以帮助我们更好地管理项目的依赖。在父项目的 POM 文件中,我们可以定义所有模块共享的依赖,这样可以避免重复的依赖定义,也方便我们管理和升级依赖。

  • 构建和部署:Maven 多模块项目的另一个优点是它可以统一管理项目的构建和部署。我们只需要在父项目中执行 Maven 命令,就可以对所有模块进行构建和部署。这大大简化了开发者的工作。

IDEA 搭建 Spring Boot 多模块工程骨架

开始动手

首先选择一个位置,新建一个名为 weblog 的工程目录,用于统一存放后端项目和前端项目,方便后续管理:

创建父项目

打开 IDEA, 依次点击菜单 File -> New -> Project, 准备新建父项目 :

注意:部分小伙伴反馈说,IDEA 通过 Spring Initializr 来创建 Spring Boot 项目, 突然不支持勾选 Java 8 了 , 可以如下图所示,点击小齿轮,将初始化链接换成阿里云的 http://start.aliyun.com, 就可以正常选择 Java 8 了:

另外:你也可以通过第二种方式 Maven Archetype 来创建多模块项目,请点击阅读下面小节内容:

《搭建 Spring Boot 多模块工程(通过 Maven Archetype)》

  • ①:选择 Spring Boot 项目初始化器;
  • ②:填写父项目名称;
  • ③:选择新建项目所在的位置;
  • ④:选择通过 Maven 来构建项目;
  • ⑤:填写 Group 组织名称,通常为公司域名倒写,如 com.quanxiaoha
  • ⑥:选择前面小节中已经安装好的 JDK 1.8 版本;
  • ⑦:选择 Java 版本,和 JDK 版本保持一致,选择 8;

点击 Next ,进入下一步,配置 Spring Boot:

  • ①:选择 Spring Boot 版本,这里暂选择一个 2.7 版本,后面我们再手动修改为 2.6.3 版本;

注意,本项目使用的 2.6.3 版本,请务必和我保持一个版本,高版本可能有相关 API 的变化,导致相关代码不适用,以及其他相关环境问题。

  • ②:点击创建项目;

因为这是个父项目,专门负责统一管理子模块、依赖版本等,创建完成后,在左边导航栏中,先删除下图中标注的无用文件:

删除成功后,目录结构如下:

接下来,开始整理一下父项目的 pom.xml 文件,整理后内容如下:

 4.0.0  org.springframework.boot spring-boot-starter-parent  2.6.3    com.quanxiaoha weblog-springboot ${revision} weblog-springboot  前后端分离博客 Weblog By 犬小哈  pom       0.0.1-SNAPSHOT 1.8 UTF-8  ${java.version} ${java.version}             aliyunmaven aliyun https://maven.aliyun.com/repository/public  

创建 web 访问模块(打包也在这个模块中进行)

接下来,我们开始创建父项目下面的子模块。在父项目上右键,添加模块 Module:

还是和上面创建父项目差不多的步骤,命名一个 weblog-web 模块,此模块是项目的入口,Maven 打包的打包插件放在这里,同时,和博客前台页面展示相关的功能也统一放在此模块下:

勾选上 Lombok 和 Spring Web 依赖,点击 create 创建模块:

创建完成后,删除掉无用的一些目录和文件,删完后,大致如下:

删除完成后,在父项目的 pom.xml 中添加该子模块,以及添加 spring-boot-maven-plugin :

  weblog-web      org.springframework.boot  spring-boot-maven-plugin     org.projectlombok lombok        

添加完成后,开始编辑 weblog-web 模块中的 pom.xml,只保留了一些需要的配置,最终配置内容如下:

 4.0.0   com.quanxiaoha weblog-springboot ${revision}  com.quanxiaoha weblog-web weblog-web weblog-web (入口项目,负责博客前台展示相关功能,打包也放在这个模块负责)    org.springframework.boot spring-boot-starter-web    org.projectlombok lombok true    org.springframework.boot spring-boot-starter-test test      org.springframework.boot spring-boot-maven-plugin   

你可能会遇到的问题

依赖爆红解决方案

若 pom.xml 文件中的依赖出现爆红等情况,通过点击右侧栏 Reload 图标,重新加载 Maven 项目来解决:

控制台出现警告解决方案

在执行 Maven 命令时,若使用 IDEA 默认的 Maven 配置,可能会导致后面打包控制台出现如下警告:

可在点击 File -> Settings 找到 Maven 选项,默认是使用 IDEA 自带的 Maven 版本, 这里将 Maven home path 设置为前面小节中,我们手动安装好的 Maven 路径,再次执行 Maven 命令,即警告信息消失了:

执行 mvn clean package 命令报错

执行 mvn clean package 等相关命令时, 控制台提示如下图所示的错误,这个问题星球内好多人反馈都有犯:

问题原因是,在子模块中的  节点下添加了  ,注意,它只需要在父级项目中添加一次即可,子模块中是无需添加这个的,一定要去掉:

创建 Admin 管理后台功能模块

再次新建一个负责 Admin 管理后台功能的子模块,命名为 weblog-module-admin ,此模块用于统一放置和 Admin 管理后台相关的功能:

依赖仅需勾选 Lombok 即可,后面需要什么再添加:

创建成功后,在父项目的 pom.xml 文件中添加该子模块:

    weblog-web  weblog-module-admin 

然后,和前面一样,删除掉哪些无用的文件夹、文件,删除完成后,如下图所示:

另外,还需要将 resource 目录下的配置文件,和 Application 启动类删除掉。配置文件统一放在 weblog-web 入口模块中来管理:

最后,再整理一下此模块的 pom.xml , 内容如下:

4.0.0com.quanxiaohaweblog-springboot${revision}com.quanxiaohaweblog-module-adminweblog-module-adminweblog-admin (负责管理后台相关功能)org.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

创建 common 通用功能子模块

依葫芦画瓢,按照上面的步骤,再次创建 weblog-module-common 子模块,此模块专门用于存放一些通用的功能,如接口的日志切面、全局异常管理等等。

创建成功后,在父项目的 pom.xml 文件中添加该子模块:

    weblog-web  weblog-module-admin  weblog-module-common 

和 weblog-mudule-admin 子模块一样,再删除掉无用的文件,最终其 pom.xml 内容如下:

4.0.0com.quanxiaohaweblog-springboot${revision}com.quanxiaohaweblog-module-commonweblog-module-commonweblog-module-common (此模块用于存放一些通用的功能)org.projectlomboklomboktrue   com.google.guava  guava org.springframework.bootspring-boot-starter-testtest

父项目统一版本管理

在父项目的 pom.xml 中,将这几个子模块统一声明一下,另外添加相关常用的工具包,如 commons-lang3 、guava :

  ...  1.18.28 31.1-jre 3.12.0      com.quanxiaoha weblog-module-admin ${revision}   com.quanxiaoha weblog-module-common ${revision}    com.google.guava guava ${guava.version}   org.apache.commons commons-lang3 ${commons-lang3.version}    

子模块之间的依赖关系

这几个子模块之间,互相还存在依赖关系,我们也需要引入一下。如入口模块 weblog-web 依赖于 weblog-module-admin 和 weblog-module-common,在其 pom.xml 添加如下:

  com.quanxiaoha weblog-module-common   com.quanxiaoha weblog-module-admin  ... 

以及 weblog-module-admin 依赖于 weblog-module-common,在其 pom.xml 添加如下:

com.quanxiaohaweblog-module-common...

测试看看,有没有报错

在 IDEA 中, 对 weblog-springboot 父项目执行 Maven 的 clean package 打包命令,看看是否能够正常给项目打包:

⚠️ 注意:企业开发中,一般都比较追求敏捷开发,可能不会写太多的单元测试。本实战项目同样为了追求开发进度,不会编写单元测试,所以多模块的单元测试并未配置完成,这里,需要如下图所示,将跳过单元测试勾选上否则,你打包的时候会报错

  • ①:执行 mvn clean 命令;
  • ②:执行 mvn package 打包命令;

如果没有问题,控制台会提示 BUILD SUCCESS 表示构建成功:

打包成功后的 Jar 包,可以在项目目录的 weblog-web 入口模块中的 /target 目录下找到:

启动该 Spring Boot 项目

进入 weblog-web 入口项目,找到 WeblogWebApplication 启动类,点击启动图标,运行此项目:

若控制台能够正确打印如下日志,则表示 Spring Boot 启动成功:

至此,搭建 Spring Boot 多模块工程就成功啦,是不是还挺简单的。

2. 多环境配置

Spring Profile 

Spring Profile 是 Spring 框架用于处理不同环境配置的解决方案。Profile 可以帮助我们在不改变应用代码的情况下,根据当前环境动态地激活或者切换不同的配置。

Spring Boot 为每个 Profile 提供了一个独立的 application.properties(或 application.yml)配置文件。默认情况下,Spring Boot 使用的是 application.properties 文件。当你激活一个特定的 Profile 时,Spring Boot 会查找名为 application-{profile}.properties 的文件,并把其中的属性加载到 Spring Environment 中。

Spring Profile 是 Spring 框架用于处理不同环境配置的解决方案。Profile 可以帮助我们在不改变应用代码的情况下,根据当前环境动态地激活或者切换不同的配置。

Spring Boot 为每个 Profile 提供了一个独立的 application.properties(或 application.yml)配置文件。默认情况下,Spring Boot 使用的是 application.properties 文件。当你激活一个特定的 Profile 时,Spring Boot 会查找名为 application-{profile}.properties 的文件,并把其中的属性加载到 Spring Environment 中。

如何创建和使用 Profile

假设我们有三个环境:开发(dev)、测试(test)、生产(prod)。那么我们可以创建以下几个配置文件:

  • application.properties: 存放所有环境通用的配置。
  • application-dev.properties: 存放开发环境的特殊配置。
  • application-test.properties: 存放测试环境的特殊配置。
  • application-prod.properties: 存放生产环境的特殊配置。

配置文件内容示例

在 application.properties 中,我们可能会配置一些公共的属性

# 应用名称app.name=Weblog

在 application-dev.properties 中,我们可以配置一些一些开发环境特定的配置,如本地调试要使用的数据库连接等:

# 数据库连接信息spring.datasource.url=jdbc:mysql://localhost:3306/dev_db

在 application-test.properties 和 application-prod.properties 中也可以类似地配置测试和生产环境的特定属性。

如何激活 Profile

在 Spring Boot 中,有多种方式可以激活 Profile:

  • 1、 在 Spring Boot 的 application.properties 或 application.yml 中设置 spring.profiles.active 属性。例如,你可以添加以下配置来激活 \"dev\" 环境:

    # 企业级项目开发中,一般项目默认会激活 dev 环境spring.profiles.active=dev
  • 2、 在命令行中设置 spring.profiles.active 系统属性。例如,你可以使用以下命令来启动你的应用,并激活 \"prod\" 环境:

    # 企业级项目开发中,针对生产环境,一般通过启动命令再指定激活 prod 环境java -jar $APP_NAME --spring.profiles.active=prod
  • 3、 在操作系统的环境变量中设置 SPRING_PROFILES_ACTIVE(这种方式比较少用到)。

开始动手

新建多环境配置文件

针对 weblog 项目来说,由于它的定位是个人博客,不涉及团队开发,我们只需要配置两个环境就 OK 了:

  • dev : 本地开发环境,兼顾测试,测试完成后直接上线;
  • prod : 生产环境;

打开 weblog-web 入口模块,将 /resources 目录下的 /static 和 /templates 都删除掉,它们用于服务端渲染的项目,因为我们是前后端分离,所以不需要:

然后,将 application.properties 的后缀改为 .yml 格式,另外,再新建 application-dev.yml 开发环境与 application-prod.yml 生产环境:

科普:什么是 .yml 格式?它和 .properties 有什么区别?

.yml(或.yaml)和.properties都是用来存储配置信息的文件格式,分别代表了 YAML(YAML Ain\'t Markup Language)和 Properties 两种格式。

YAML(.yml 或 .yaml)

YAML 是一种人类可读的数据序列化标准,通常用于配置文件和在网络上交换数据,如 API 交互等。YAML 以数据为中心,采用缩进式层次结构,从而使得配置文件更加清晰,易于阅读和书写。此外,YAML 支持复杂的数据结构,如列表和键值对,因此,YAML 的使用适用于需要表示复杂数据结构的场合。

一个简单的 YAML 文件示例:

person: name: John Doe age: 30 hobbies: - Reading - Sports

Properties(.properties)

Properties 格式是 Java 平台原生的一种配置文件格式。它的格式简单,每一行都是一个键值对,键和值之间用等号(=)或冒号(:)分隔。Properties 文件不支持复杂的数据结构,只支持字符串类型的键值对,因此,它的使用适用于简单的配置场景。

一个简单的 Properties 文件示例:

person.name=John Doeperson.age=30

YAML vs Properties

  • 可读性:YAML 的可读性更强,它采用缩进表示层次关系,而 Properties 文件则通过点分隔符表示层次关系。
  • 数据结构:YAML 支持复杂的数据结构,包括列表和映射,而 Properties 文件只支持字符串类型的键值对。
  • 兼容性:Properties 是 Java 平台的标准配置格式,几乎所有的 Java 程序都可以直接读取。而 YAML 需要相应的解析库才能解析。

在 Spring Boot 应用中,你可以根据自己的实际需求,选择使用 YAML 还是 Properties 格式的配置文件。如果你的配置比较简单,Properties 格式可能会更好些。如果你的配置比较复杂,或者你希望配置文件更具可读性,那么 YAML 格式可能是更好的选择。weblog 项目选择使用 .yml 格式。

激活默认环境

编辑 application.yml, 添加通用配置:

spring: profiles: # 默认激活 dev 环境 active: dev

由于目前还是项目搭建阶段,暂时就配置以上内容,后面需要啥,如数据库连接信息、Elasticsearch 连接信息等,用到时再添加。

验证是否生效

配置完成后,再次启动项目,观察控制台日志,若看到 The following profiles are active: dev , 则表示激活 dev 环境成功啦:

3. 配置 Lombok

Lombok 是一个超酷的 Java 库,它能让你避免编写那些冗余的 Java 样板式代码,如对象中的 getsettoString 等方法,解放你的双手,堪称偷懒神器,在企业级项目开发中,是必会的一个库。

Lombok 的用途

  1. 简化 Getter 和 Setter 方法: 在传统的 Java 开发中,你经常需要为每个类的属性手动编写 Getter 和 Setter 方法,但是有了 Lombok,你只需要在属性上加上 @Getter 和 @Setter 注解,Lombok 就会为你自动生成这些方法。
  2. 自动生成构造函数: 通过 @NoArgsConstructor@RequiredArgsConstructor 或 @AllArgsConstructor 注解,你可以快速生成无参构造函数、带有必需参数的构造函数或者带有全部参数的构造函数。
  3. 自动生成 equals 和 hashCode 方法: 通过 @EqualsAndHashCode 注解,Lombok 会根据类的字段自动生成 equals() 和 hashCode() 方法,让你的类更易于比较和使用在集合中。
  4. 日志记录更轻松: 使用 @Slf4j 注解,你可以直接在类中使用 log 对象,而无需手动创建日志记录器。
  5. 简化异常抛出: 通过 @SneakyThrows 注解,你可以在方法中抛出受检异常,而无需显式地在方法上声明或捕获它们。
  6. 数据类简化: 使用 @Data 注解,Lombok 会为你自动生成所有常用方法,如 Getter、Setter、toString() 等,让你的数据类更加简洁。
  7. 链式调用: 使用 @Builder 注解,Lombok 可以帮你创建一个更优雅的构建器模式,让你的对象初始化更加流畅。

项目中添加 Lombok 依赖

想要在项目中使用 Lombok, 首先, 你需要在项目中添加 Lombok 依赖。前面小节中,小哈其实已经将 Lombok 依赖添加好了,这里再提一下。

针对通过 Maven 构建的项目来说,只需要在项目的 pom.xml 文件中添加以下依赖:

 org.projectlombok lombok 1.18.28 provided

IDEA 配置 Lombok 插件

TIP: IDEA 2020.3 及以上版本已经内置安装了 Lombok 插件,如果你的 IDEA 版本大于该版本,则不用管,否则需要按下面的步骤,来手动安装 Lombok 插件。

除了添加依赖外,还需要在 IDEA 中安装 Lombok 插件,才能正式的使用 Lombok。

开始安装

根据你的系统依次点击菜单:

  • Windows 系统:File -> Settings... -> Plugins;
  • Mac 系统:IntelliJ IDEA -> Preferences -> Plugins;

点击 Marketplace , 进入插件市场, 输入关键词 lombok, 搜索该插件:

安装 Lombok 插件

然后,点击 Install 按钮开始安装,小哈这里已经安装过了,所以显示的打钩。安装完成后,点击 Apply 按钮应用设置即可。

4. Spring Boot 整合 Logback 日志

在构建任何应用程序时,良好的日志管理都是必不可少的。日志可以帮助我们监控、调试和跟踪代码的运行情况。 

什么是 Logback?

Logback 是日志框架 SLF4J 的一个实现,它被设计用来替代 log4j。Logback 提供了更高的性能,更丰富的日志功能和更好的配置选项。

为什么要用它?

在 Spring Boot 中,Logback 是默认的日志实现,至于官方为何用它作为默认日志组件,有以下几个原因:

  1. 性能:Logback 在性能上超越了许多其他的日志实现,尤其是在高并发环境下。
  2. 灵活性:Logback 提供了高度灵活的日志配置方式,支持从 XML、Groovy 以及编程式的方式进行配置。
  3. 功能丰富:除了基本的日志功能,Logback 还提供了如日志归档、日志级别动态修改、事件监听等高级功能。
  4. 与 SLF4J 集成:SLF4J 是一个日志门面(facade),使得应用程序可以在运行时更换日志实现。Logback 作为 SLF4J 的一个原生实现,可以无缝地与其集成。
  5. 与 Spring Boot 的自动配置集成:Spring Boot 提供了对 Logback 的自动配置,这意味着开发者无需手动配置 Logback,只需提供一个简单的配置文件即可。

引入依赖

由于 Spring Boot 默认使用 Logback,所以当你在 pom.xml 中加入 spring-boot-starter-web 依赖时,它会自动包含 Logback 相关依赖,无需额外添加 Logback 依赖。编辑 weblog-web 入口模块的 pom.xml, 添加如下依赖:

 org.springframework.boot spring-boot-starter-web

自定义 Logback 配置

为了满足特定的日志需求,我们通常会自定义 Logback 配置。这里需要注意,配置文件我们统一放置在 weblog-web 模块中,方便统一管理。然后在 src/main/resources 目录下,创建一个名为 logback-weblog.xml 的文件。

内容如下:

        <!---->   ${LOG_FILE}-%i.log3010MB    ${FILE_LOG_PATTERN}                

因为打印日志到文件只需要在生产环境开启就行了,所以,使日志生效的配置放到 application-prod.yml 文件中就行了:

#=================================================================# log 日志#=================================================================logging: config: classpath:logback-weblog.xml

打印日志

为了测试一下日志是否能够正常打印,我们在单元测试包下的 WeblogWebApplicationTests 类中:

新建一个 testLog() 测试方法,同时添加 Lombok 的 @Slf4j 日志注解,它可以帮助我们自动的生成日志实例,示例代码如下:

package com.example.weblog.web;import lombok.extern.slf4j.Slf4j;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest@Slf4jclass WeblogWebApplicationTests { @Test void contextLoads() { } @Test void testLog() { log.info(\"这是一行 Info 级别日志\"); log.warn(\"这是一行 Warn 级别日志\"); log.error(\"这是一行 Error 级别日志\"); // 占位符 String author = \"犬小哈\"; log.info(\"这是一行带有占位符日志,作者:{}\", author); }}

控制台日志

运行该测试方法,若控制台日志输出如下,表示日志组件运行正常运行,在后续的功能开发中,我们会频繁地使用到它:

日志输出到文件中

接下来,我们再验证一下生产环境是否能够使文件输出到文件中。先将 application.yml 的环境改为 prod ,一旦激活 prod, 则日志将被输出到文件中:

spring: profiles: # 默认激活 dev 环境 active: prod

因为小哈用的 Windows 系统做的演示,还需要修改 logback-weblog.xml , 将日志输出路径自定义为 Windows 路径:

💡 测试完成后,记得将 profile 重新改回 dev 环境,以及路径改回 Linux 格式路径。

重新运行该单元测试,查看该路径下是否正确输出日志文件:

可以看到日志文件输出正常。至此,Spring Boot 整合 Logback 日志就算搞定啦~

5. Spring Boot 自定义注解,实现 API 请求日志切面

在后端业务中,对每次请求的入参、被请求类、方法,以及出参、执行耗时等信息进行日志打印,是很有必要的,有了这些信息,当某个接口出现问题时,可以帮助我们快速完成问题的追踪。那么,Spring Boot 中要如何实现呢? 

什么是自定义注解 (Custom Annotations)?

Java 注解是从 Java 5 开始引入的,它为我们提供了一种元编程的方法,允许我们在不改变代码逻辑的情况下为代码添加元数据。这些元数据可以在编译时或运行时通过反射被访问。

自定义注解就是用户定义的,用于为代码提供元数据的注解。例如,本小节中自定义的 @ApiOperationLog 注解,它用来表示一个方法在执行时需要被记录日志。

什么是 AOP (面向切面编程)?

AOP(Aspect-Oriented Programming,面向切面编程)是一个编程范式,它提供了一种能力,让开发者能够模块化跨多个对象的横切关注点(例如日志、事务管理、安全等)。

主要概念包括:

  • 切点 (Pointcuts): 定义在哪里应用切面(即在哪里插入横切关注点的代码)。
  • 通知 (Advices): 定义在特定切点上要执行的代码。常见的通知类型有:前置通知、后置通知、环绕通知等。
  • 切面 (Aspects): 切面将切点和通知结合起来,定义了在何处和何时应用特定的逻辑。

例如,使用AOP,我们可以为所有使用 @ApiOperationLog 注解的方法自动添加日志逻辑,而不需要在每个方法中手动添加。

6. Spring Boot 通过 MDC 实现日志跟踪

我们将在 Spring Boot 中通过 MDC 实现日志追踪功能。

什么是 MDC ? 为什么需要它?

MDC(Mapped Diagnostic Context)是 SLF4J 和 log4j 等日志框架提供的一种方案,它允许开发者将一些特定的数据(如用户ID、请求ID等)存储到当前线程的上下文中,使得这些数据可以在日志消息中使用。这对于跟踪多线程或高并发应用中的单个请求非常有用。

在高并发环境中,由于多个请求可能同时处理,日志消息可能会交错在一起。使用MDC,我们可以为每个请求分配一个唯一的标识,并将该标识添加到每条日志消息中,从而方便地区分和跟踪每个请求的日志

7. Spring Boot 实现优雅的参数校验

在日常的 Web 开发中,请求参数校验是一个非常基础且重要的环节。通过校验,我们可以确保每次接口请求中,入参的数据是有效、安全且合规的,避免数据库中出现脏数据。

JSR 380 参数校验注解

Spring Boot 提供了简洁的方法,让我们能够利用 Java 校验 API (JSR 380) 中定义的注解进行参数校验。JSR 380,也被称为 Bean Validation 2.0,是 Java Bean 验证规范的一个版本。该规范定义了一系列注解,用于验证 Java Bean 对象的属性,确保它们满足某些条件或限制。

以下是 JSR 380 中提供的主要验证注解及其描述:

  1. @NotNull: 验证对象值不应为 null。
  2. @AssertTrue: 验证布尔值是否为 true。
  3. @AssertFalse: 验证布尔值是否为 false。
  4. @Min(value): 验证数字是否不小于指定的最小值。
  5. @Max(value): 验证数字是否不大于指定的最大值。
  6. @DecimalMin(value): 验证数字值(可以是浮点数)是否不小于指定的最小值。
  7. @DecimalMax(value): 验证数字值(可以是浮点数)是否不大于指定的最大值。
  8. @Positive: 验证数字值是否为正数。
  9. @PositiveOrZero: 验证数字值是否为正数或零。
  10. @Negative: 验证数字值是否为负数。
  11. @NegativeOrZero: 验证数字值是否为负数或零。
  12. @Size(min, max): 验证元素(如字符串、集合或数组)的大小是否在给定的最小值和最大值之间。
  13. @Digits(integer, fraction): 验证数字是否在指定的位数范围内。例如,可以验证一个数字是否有两位整数和三位小数。
  14. @Past: 验证日期或时间是否在当前时间之前。
  15. @PastOrPresent: 验证日期或时间是否在当前时间或之前。
  16. @Future: 验证日期或时间是否在当前时间之后。
  17. @FutureOrPresent: 验证日期或时间是否在当前时间或之后。
  18. @Pattern(regexp): 验证字符串是否与给定的正则表达式匹配。
  19. @NotEmpty: 验证元素(如字符串、集合、Map 或数组)不为 null,并且其大小/长度大于0。
  20. @NotBlank: 验证字符串不为 null,且至少包含一个非空白字符。
  21. @Email: 验证字符串是否符合有效的电子邮件格式。

除了上述的标准注解,JSR 380 也支持开发者定义和使用自己的自定义验证注解。此外,这个规范还提供了一系列的APIs和工具,用于执行验证和处理验证结果。大部分现代Java框架(如 Spring 和 Jakarta EE)都与 JSR 380 兼容,并支持其验证功能。

8. Spring Boot 自定义响应工具类

在开发 RESTful API 时,为了保持响应结构的一致性,公司内部一般都有标准化的响应格式。这不仅可以提高代码的可维护性,还可以帮助前端开发者更容易地处理和解析 API 响应。

9. Spring Boot 实现全局异常管理

在开发大型 Web 应用时,统一的异常处理是保持代码整洁和维护性的关键所在。Spring Boot 提供了方便的方法来帮助我们实现全局的异常管理。

10. 全局异常处理器+参数校验

之前的参数校验还不够优雅!每次都需要在 controller 层手动获取校验错误,然后再返回参数,一坨一坨的,每次都要手动写未免太难看了。本小节中,我们将使用全局异常管理器来优化这块,告别每次手动获取校验错误信息再返回。

11. 整合 Knife4j:提升接口调试效率

Knife4j 是什么?

Knife4j 是一个为 Java 项目生成和管理 API 文档的工具。实际上,它是 Swagger UI 的一个增强工具集,旨在让 Swagger 生成的 API 文档更优雅、更强大。

Knife4j 主要功能

  • 美观的 UI:相比于原生 Swagger UI,Knife4j 提供了更加人性化和美观的界面设计。
  • 丰富的文档交互功能:支持在线调试、请求参数动态输入、接口排序等。
  • 个性化配置:可自定义 API 文档的界面风格,实现文档界面的个性化展示。

为什么要用它?

小伙伴们可能会疑惑,咱这不是一个人就把前后端包办吗?还搞啥 API 文档,是不是多此一举了。其实,我们主要想用的是它的在线调试功能,在前面小节中,小哈在调试接口这块,都是通过 Postman 来进行的,每当测试一个新的接口时,就不得不手动填写请求路径,组装 JSON 入参格式,其实还是比较繁琐的。

有了 Knife4j,因为它支持在线调试,这块的时间就可以省下来了。本小节中,我们就来看看,如何通过 Knife4j 提升接口调试效率。

12. 自定义 Jackson 序列化、反序列化,支持 Java 8 日期新特性

ava 8 中,引入了新的时间和日期 API,相比较老旧的 Date , 它使用起来更加便捷,用过的都懂。本小节中自定义 Spring Boot 内置的 JSON 框架 Jackson,让出入参支持序列化、反序列化 Java 8 中新的日期 API : LocalDateTimeLocalDateLocalTime。