SpringBoot后端工程搭建

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

什么是多模块项目

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

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

为什么要使用多模块项目

主要有以下几个原因:

  • 代码组织:在大型项目中,我们经常需要把代码分成多个模块,以便更好地组织代码。每个模块可以聚焦于一个特定的功能或领域,这样可以提高代码的可读性和可维护性。
  • 依赖管理:Maven 多模块项目可以帮助我们更好地管理项目的依赖。在父项目的 POM 文件中,我们可以定义所有模块共享的依赖,这样可以避免重复的依赖定义,也方便我们管理和升级依赖。
  • 构建和部署:Maven 多模块项目的另一个优点是它可以统一管理项目的构建和部署。我们只需要在父项目中执行 Maven 命令,就可以对所有模块进行构建和部署。这大大简化了开发者的工作。

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

构建父项目 - weblog

没有找到JDK8? 服务器url替换成aliyun,否则无法使用jdk8

image-20240107111727516

项目初始化目录,删除无用的文件

image-20240107112249405

创建 web 访问模块

这是项目的入口,maven 打包的打包插件在这里存放,同时,博客的前端相关内容也统一存放在这里。

image-20240107112343774

勾选依赖 Lombok 和 Spring Web

image-20240107112431469

创建后台管理模块

该模块负责统一放置和管理后台相关的功能

依赖仅用 Lombok,后续再增加新的模块

image-20240107113025777

创建通用模块

该模块存放一些通用的功能,比如接口的日志切面,全局异常管理

image-20240107140837391

pom 文件解析

weblog

在父项目的 pom.xml 文件中对项目进行统一管理

对项目的版本号进行统一管理

  1. 项目版本号,主要是涉及项目自身的开发版本,JDK 版本,项目编码
  2. Maven 相关内容,依赖的是 JDK 版本
  3. 项目依赖包的版本号
<!-- 版本号统一管理 -->
<properties>
<!-- 项目版本号 -->
<revision>0.0.1-SNAPSHOT</revision>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<!-- Maven 相关 -->
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>

<!-- 依赖包版本 -->
<lombok.version>1.18.28</lombok.version>
<guava.version>31.1-jre</guava.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<jackson.version>2.15.2</jackson.version>

</properties>

项目相关依赖的管理

  1. 子模块的名称以及版本号
  2. 常用依赖工具的名称以及版本号
<!-- 统一依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-admin</artifactId>
<version>${revision}</version>
</dependency>

<dependency>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-common</artifactId>
<version>${revision}</version>
</dependency>

<!-- 常用工具库 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>

<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

项目的构建设置 这里添加了spring-boot-maven-plugin

<build>
<!-- 统一插件管理 -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>

weblog-web

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 指定父项目为 weblog-springboot -->
<parent>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-springboot</artifactId>
<version>${revision}</version>
</parent>

<groupId>com.sakurasep</groupId>
<artifactId>weblog-web</artifactId>
<name>weblog-web</name>
<description>weblog-web (入口项目,负责博客前台展示相关功能,打包也放在这个模块负责)</description>

<dependencies>
<dependency>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-common</artifactId>
</dependency>

<dependency>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-admin</artifactId>
</dependency>

<!-- Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 免写冗余的 Java 样板式代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

weblog-admin

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 指定父项目为 weblog-springboot -->
<parent>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-springboot</artifactId>
<version>${revision}</version>
</parent>

<groupId>com.sakurasep</groupId>
<artifactId>weblog-admin</artifactId>
<name>weblog-admin</name>
<description>weblog-admin (负责管理后台相关功能)</description>

<dependencies>
<dependency>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-common</artifactId>
</dependency>
<!-- 免写冗余的 Java 样板式代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>

weblog-common

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sakurasep</groupId>
<artifactId>weblog-springboot</artifactId>
<version>${revision}</version>
</parent>

<groupId>com.sakurasep</groupId>
<artifactId>weblog-common</artifactId>
<name>weblog-common</name>
<description>weblog-module-common (此模块用于存放一些通用的功能)</description>

<dependencies>
<!-- 免写冗余的 Java 样板式代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- AOP 切面 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>

</project>

测试项目

执行 mvn clean

image-20240107141514819

执行 mvn package

image-20240107141639434

运行该 Spring Boot 项目,在 weblog-web 找到 WeblogWebApplication 启动类

运行在 8080 端口

image-20240107141844804

Spring Boot 多环境配置

多环境配置文件

在 weblog-web 添加多环境配置文件

  • application.yml 用于默认配置
  • application-dev.yml 用于开发环境
  • application-test.yml 用于测试环境
  • application-prod.yml 用于生产环境

相比于 properties 格式的配置文件,yaml 格式的显然可阅读性更好

image-20240107143300065

在默认配置文件中激活 dev 环境

image-20240107143509797

启动项目测试,出现以下标注语句表示激活成功

image-20240107143548478

配置 Lombok

Lombok 的优点

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

    自定义 logback 配置

    logback的优点

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

    添加logback

    添加依赖 spring boot 默认使用 logback 为默认的日志系统,只需要添加 spring-boot-starter-web 依赖就会自动包含 logback 相关依赖

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    配置 logback

    在 weblog-web 的配置文件夹中添加 logback-weblog.xml

    image-20240107144745067

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration >
    <jmxConfigurator/>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />

    <!-- 应用名称 -->
    <property scope="context" name="appName" value="weblog" />
    <!-- 自定义日志输出路径,以及日志名称前缀 -->
    <property name="LOG_FILE" value="/app/weblog/logs/${appName}.%d{yyyy-MM-dd}"/>
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
    <!--<property name="CONSOLE_LOG_PATTERN" value="${FILE_LOG_PATTERN}"/>-->

    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!-- 日志文件输出的文件名 -->
    <FileNamePattern>${LOG_FILE}-%i.log</FileNamePattern>
    <!-- 日志文件保留天数 -->
    <MaxHistory>30</MaxHistory>
    <!-- 日志文件最大的大小 -->
    <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    <maxFileSize>10MB</maxFileSize>
    </TimeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <!-- 格式化输出:%d 表示日期,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度 %errorMessage:日志消息,%n 是换行符-->
    <pattern>${FILE_LOG_PATTERN}</pattern>
    </encoder>
    </appender>

    <!-- dev 环境(仅输出到控制台) -->
    <springProfile name="dev">
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="info">
    <appender-ref ref="CONSOLE" />
    </root>
    </springProfile>

    <!-- prod 环境(仅输出到文件中) -->
    <springProfile name="prod">
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
    <appender-ref ref="FILE" />
    </root>
    </springProfile>
    </configuration>

    在生产环境的 application-prod.yml 中添加 log 输出

    image-20240107144834566

    在单元测试包下的测试类中加入以下代码

    image-20240107145235419

    package com.sakurasep.weblogweb;

    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;

    @SpringBootTest
    @Slf4j
    class WeblogWebApplicationTests {

    @Test
    void contextLoads() {
    }

    @Test
    void testLog() {
    log.info("这是一行 Info 级别日志");
    log.warn("这是一行 Warn 级别日志");
    log.error("这是一行 Error 级别日志");

    // 占位符
    String author = "上杉九月";
    log.info("这是一行带有占位符日志,作者:{}", author);
    }

    }

    运行该测试方法

    image-20240107145339361

    激活生产环境看是否输出到文件

    image-20240107145455726

    修改 logback-weblog.xml 中的输出路径

    image-20240107145647976

    测试输出

    image-20240107145759496

    测试输出结束记得将路径改回原本的路径,并重新改成 dev 环境

    自定义注解,实现 API 请求日志切面

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

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

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

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

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

    主要概念包括:

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

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

    添加依赖

    在父项目的 pom.xml 添加配置

    <!-- 版本号统一管理 -->
    <properties>
    <jackson.version>2.15.2</jackson.version>
    </properties>

    <!-- 统一依赖管理 -->
    <dependencyManagement>
    <dependencies>
    <!-- Jackson -->
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
    </dependency>

    </dependencies>
    </dependencyManagement>

    因为日志切面属于前后端通用的功能,所以在 weblog-common 中也要引用依赖

    <!-- AOP 切面 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    <!-- Jackson -->
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    </dependency>

    实现自定义注解

    在 weblog-common 新建一个 aspect 包

    package com.sakurasep.weblogcommon.aspect;

    import java.lang.annotation.*;


    //这个元注解用于指定注解的保留策略,即注解在何时生效。RetentionPolicy.RUNTIME 表示该注解将在运行时保留,这意味着它可以通过反射在运行时被访问和解析。
    @Retention(RetentionPolicy.RUNTIME)
    //这个元注解用于指定注解的目标元素,即可以在哪些地方使用这个注解。ElementType.METHOD 表示该注解只能用于方法上。这意味着您只能在方法上使用这个特定的注解。
    @Target({ElementType.METHOD})
    //这个元注解用于指定被注解的元素是否会出现在生成的Java文档中。如果一个注解使用了 @Documented,那么在生成文档时,被注解的元素及其注解信息会被包含在文档中。这可以帮助文档生成工具(如 JavaDoc)在生成文档时展示关于注解的信息。
    @Documented
    public @interface ApiOperationLog {
    /**
    * API 功能描述
    *
    * @return
    */
    String description() default "";

    }

    创建 JSON 工具类

    在 weblog-common 模块下创建 utils 包,统一放置工具类,新建 JsonUtil 工具类

    package com.sakurasep.weblogcommon.utils;

    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import lombok.extern.slf4j.Slf4j;

    /**
    * @author sakurasep
    * * @date 2024/1/7
    * json 工具类 用于将传入的对象打印成 json 字符串
    **/
    @Slf4j
    public class JsonUtil {

    private static final ObjectMapper INSTANCE = new ObjectMapper();

    public static String toJsonString(Object obj) {
    try {
    return INSTANCE.writeValueAsString(obj);
    } catch (JsonProcessingException e) {
    return obj.toString();
    }
    }
    }

    定义日志切面类

    在 aspect 包中新建切面类 ApiOperationLogAspect

    package com.sakurasep.weblogcommon.aspect;

    import com.sakurasep.weblogcommon.utils.JsonUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.MDC;
    import org.springframework.stereotype.Component;

    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.UUID;
    import java.util.function.Function;
    import java.util.stream.Collectors;

    /**
    * @author sakurasep
    * * @date 2024/1/7
    **/
    @Aspect
    @Component
    @Slf4j
    public class ApiOperationLogAspect {

    /** 以自定义 @ApiOperationLog 注解为切点,凡是添加 @ApiOperationLog 的方法,都会执行环绕中的代码 */
    @Pointcut("@annotation(com.sakurasep.weblogcommon.aspect.ApiOperationLog)")
    public void apiOperationLog() {}

    /**
    * 环绕
    * @param joinPoint
    * @return
    * @throws Throwable
    */
    @Around("apiOperationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    try {
    // 请求开始时间
    long startTime = System.currentTimeMillis();

    // MDC
    MDC.put("traceId", UUID.randomUUID().toString());

    // 获取被请求的类和方法
    String className = joinPoint.getTarget().getClass().getSimpleName();
    String methodName = joinPoint.getSignature().getName();

    // 请求入参
    Object[] args = joinPoint.getArgs();
    // 入参转 JSON 字符串
    String argsJsonStr = Arrays.stream(args).map(toJsonStr()).collect(Collectors.joining(", "));

    // 功能描述信息
    String description = getApiOperationLogDescription(joinPoint);

    // 打印请求相关参数
    log.info("====== 请求开始: [{}], 入参: {}, 请求类: {}, 请求方法: {} =================================== ",
    description, argsJsonStr, className, methodName);

    // 执行切点方法
    Object result = joinPoint.proceed();

    // 执行耗时
    long executionTime = System.currentTimeMillis() - startTime;

    // 打印出参等相关信息
    log.info("====== 请求结束: [{}], 耗时: {}ms, 出参: {} =================================== ",
    description, executionTime, JsonUtil.toJsonString(result));

    return result;
    } finally {
    MDC.clear();
    }
    }

    /**
    * 获取注解的描述信息
    * @param joinPoint
    * @return
    */
    private String getApiOperationLogDescription(ProceedingJoinPoint joinPoint) {
    // 1. 从 ProceedingJoinPoint 获取 MethodSignature
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();

    // 2. 使用 MethodSignature 获取当前被注解的 Method
    Method method = signature.getMethod();

    // 3. 从 Method 中提取 LogExecution 注解
    ApiOperationLog apiOperationLog = method.getAnnotation(ApiOperationLog.class);

    // 4. 从 LogExecution 注解中获取 description 属性
    return apiOperationLog.description();
    }

    /**
    * 转 JSON 字符串
    * @return
    */
    private Function<Object, String> toJsonStr() {
    return arg -> JsonUtil.toJsonString(arg);
    }

    }

    添加包扫描

    在启动类中添加 @ComponentScan,扫描 com.sakurasep 包下的所有类

    package com.sakurasep.weblogweb;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;

    @SpringBootApplication
    @ComponentScan({"com.sakurasep.*"})
    public class WeblogWebApplication {

    public static void main(String[] args) {
    SpringApplication.run(WeblogWebApplication.class, args);
    }

    }

    新增测试接口

    在 weblog-web 模块中

    新建接口 创建 controller 包用于存放统一接口,创建 model 包用于放置 pojo 对象

    创建 User 类

    package com.sakurasep.weblogweb.model;

    import lombok.Data;

    /**
    * @author sakurasep
    * * @date 2024/3/12
    **/
    @Data
    public class User {
    private String username;
    private Integer sex;

    }

    创建 TestController 类,路径为 /test

    package com.sakurasep.weblogweb.controller;

    import com.sakurasep.weblogcommon.aspect.ApiOperationLog;
    import com.sakurasep.weblogweb.model.User;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;

    /**
    * @author sakurasep
    * * @date 2024/3/12
    **/
    @RestController
    @Slf4j
    public class TestController {
    // 路径映射到/test
    @PostMapping("/test")
    // 注解
    @ApiOperationLog(description = "测试接口")
    public User test(@RequestBody User user){
    return user;
    }
    }


    测试 Test 接口

    使用 postman 以 json 的格式请求 /test

    image-20240312153623018

    请求参数

    image-20240312153647898

    出参

    image-20240312153816881

    控制台输出日志

    image-20240312153755009


    关于我

    ">