程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Spring

    • Spring6 - 概述
    • Spring6 - 入门
    • Spring6 - IOC(基于XML)
    • Spring6 - IOC(基于注解)
    • spring6 - FactoryBean
    • Spring6 - Bean的作用域
    • Spring6 - Bean生命周期
    • Spring6 - Bean循环依赖
    • Spring6 - 手写IOC容器
    • Spring6 - AOP
    • Spring6 - 自定义注解
    • Spring6 - Junit
    • Spring6 - 事务
    • Spring6 - Resource
    • Spring6 - 国际化
    • Spring6 - 数据校验
    • Spring6 - Cache
    • Spring集成Swagger2
      • 一、引入依赖
      • 二、Swagger 配置
        • 创建 Swagger 配置类
        • 常见错误及解决方案
      • 三、配置资源访问权限
      • 四、编写测试接口类
      • 五、查看接口文档
      • 六、功能扩展:通过配置文件管理 Swagger 启停
        • 1. 配置文件中添加 Swagger 开关
        • 2. 修改 Swagger 配置类以读取配置项
        • 3. 切换环境时修改配置文件
      • 七、实战案例
        • 1. 实体类 (Product.java)
        • 2. 控制器类 (ProductController.java)
  • Spring生态
  • Spring
scholar
2025-01-01
目录

Spring集成Swagger2

# Spring 集成 Swagger2

前言

  • 现在要维护的项目是前几年的旧项目,架构是Spring5 + SpringMVC + SpringJDBC,并非SpringBoot项目,SpringBoot项目集成相对更简单一点。

  • 单纯Spring项目集成Swagger的情况不多,网上虽有例子,但是因项目各自情况,照搬总有错误,因此把自己的经验记录下来。

# 一、引入依赖

首先,需要在项目的 pom.xml 文件中添加 Swagger2 相关的依赖项。确保项目使用的是 Maven 作为构建工具。

<dependencies>
    <!-- Swagger2 核心依赖 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    
    <!-- Swagger2 UI 依赖,用于生成可视化的 API 文档界面 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
    
    <!-- 其他必要依赖(根据项目实际情况添加) -->
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

说明:

  • springfox-swagger2:Swagger2 的核心依赖,用于生成 API 文档。
  • springfox-swagger-ui:提供 Swagger 的前端界面,便于查看和测试 API。

注意事项:

  • 确保项目中不存在 Swagger 相关的版本冲突,避免因依赖版本不兼容导致的问题。
  • 如果项目中使用了 Spring Boot 以外的其他配置管理工具,需根据实际情况调整依赖管理。

# 二、Swagger 配置

# 创建 Swagger 配置类

在项目中创建一个专门的配置类,用于配置 Swagger 的各项参数。

package com.scholar.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Swagger 配置类
 * 
 * 该类用于配置 Swagger2 的基本参数,包括扫描的包路径、API 信息等。
 * 
 * @Author xhp
 * @Date 2022/10/26
 */
@Configuration
@EnableSwagger2  // 启用 Swagger2
@EnableWebMvc     // 启用 Spring MVC
@ComponentScan(basePackages = {
    "com.scholar.controller"  // 扫描的控制器包路径
})
@PropertySource(value = "classpath:config/config.properties", ignoreResourceNotFound = true) // 加载配置文件
public class SwaggerConfig {

    // 从配置文件中读取 Swagger 启用状态
    @Value("${swagger.enabled}")
    private boolean enabled;

    /**
     * 创建 Docket Bean,配置 Swagger 的核心参数
     * 
     * @return Docket 对象
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enabled)  // 根据配置文件决定是否启用 Swagger
                .apiInfo(apiInfo())  // 设置 API 基本信息
                .select()
                // 仅扫描带有 @ApiOperation 注解的方法
                .apis(RequestHandlerSelectors.withMethodAnnotation(io.swagger.annotations.ApiOperation.class))
                // 选择所有路径
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 配置 API 的基本信息,如标题、描述、联系人等
     * 
     * @return ApiInfo 对象
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("标题:***_接口文档")  // 设置文档标题
                .description("这里是接口文档的详细描述信息")  // 设置文档描述
                .contact(new Contact("scholar", "https://example.com", "scholar@example.com"))  // 设置联系人信息
                .version("版本号:2.0")  // 设置版本号
                .build();
    }


    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

详细说明:

  1. 注解解析:
    • @Configuration:声明这是一个配置类。
    • @EnableSwagger2:启用 Swagger2 功能。
    • @EnableWebMvc:启用 Spring MVC 功能。
    • @ComponentScan:指定扫描的包路径,确保 Swagger 能够扫描到控制器。
    • @PropertySource:加载外部配置文件,用于管理 Swagger 的启用状态。
  2. Docket Bean:
    • DocumentationType.SWAGGER_2:指定文档类型为 Swagger2。
    • .enable(enabled):根据配置文件决定是否启用 Swagger,方便在不同环境下控制 Swagger 的启停。
    • .apiInfo(apiInfo()):设置 API 的基本信息。
    • .select():开始构建 API 选择器。
    • .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)):仅扫描带有 @ApiOperation 注解的方法,避免扫描无关的类和方法。
    • .paths(PathSelectors.any()):扫描所有路径。
  3. ApiInfo 配置:
    • title:设置文档标题。
    • description:设置文档描述。
    • contact:设置联系信息,可以填写姓名、网址和邮箱。
    • version:设置文档版本。

# 常见错误及解决方案

在集成 Swagger2 的过程中,可能会遇到以下常见错误及其解决方案:

  1. 错误提示:Unable to infer base url. This is common when using dynamic servlet registration or when the API is behind an API Gateway...

    原因: 缺少 @EnableWebMvc 注解,导致 Swagger 无法正确推断基础 URL。

    解决方案: 在 Swagger 配置类上添加 @EnableWebMvc 注解。

    @EnableWebMvc
    
    1
  2. 错误提示:No operations defined in spec!

    原因: 缺少 @ComponentScan 注解或扫描的包路径不正确,导致 Swagger 未能扫描到任何 API 操作。

    解决方案: 确保在 Swagger 配置类上添加 @ComponentScan 注解,并正确指定控制器所在的包路径。

    @ComponentScan(basePackages = {
        "com.xhp.controller"  // 确保此路径正确
    })
    
    1
    2
    3
  3. 个别开发者在项目中出现 Unable to infer base url 弹窗错误

    原因: 该错误可能由多种原因引起,如本地环境配置问题、依赖版本不兼容等。

    解决方案:

    • 确认所有开发者的项目依赖版本一致。
    • 尝试降低 Swagger 版本,例如使用 2.6.0 版本。
    • 检查网络配置和代理设置,确保 Swagger UI 能够正常访问 API 文档。
    <!-- 降低 Swagger 版本 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.0</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.0</version>
    </dependency>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

# 三、配置资源访问权限

在项目中通常会使用权限控制框架,如 Apache Shiro、Spring Security 或自定义的拦截器(Interceptor)来控制访问权限。为了确保 Swagger 的资源能够被正常访问,需要在权限控制配置中为 Swagger 提供的资源路径添加免认证权限。

需要添加的 URL 路径:

  1. /swagger-ui.html:Swagger UI 的主页面。
  2. /webjars/**:Swagger UI 所需的静态资源,如 JavaScript、CSS 等。

示例:基于 Spring Security 的配置

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 其他安全配置
            .authorizeRequests()
                // 允许访问 Swagger UI
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                // 其他路径需要认证
                .anyRequest().authenticated()
            .and()
            // 其他配置,如表单登录、HTTP Basic 等
            .formLogin()
            .and()
            .httpBasic();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

说明:

  • antMatchers("/swagger-ui.html").permitAll():允许所有用户访问 Swagger UI 页面。
  • antMatchers("/webjars/**").permitAll():允许所有用户访问 Swagger UI 所需的静态资源。
  • anyRequest().authenticated():其他所有请求需要认证。

注意事项:

  • 根据实际使用的权限框架调整配置。
  • 确保以上配置在权限框架的规则中优先级较高,避免被其他规则覆盖。

# 四、编写测试接口类

为了验证 Swagger 的集成是否成功,可以编写一个简单的控制器类,并添加 Swagger 的注解。

package com.scholar.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.xhp.model.ApiResult;
import com.xhp.model.User;

/**
 * Swagger 测试控制器
 * 
 * 用于测试 Swagger 文档的生成情况。
 * 
 * @Author scholar
 * @Date 2022/10/26
 */
@Api(tags = "接口文档测试")  // Swagger 标签,用于分组展示
@RequestMapping("/test")
@Controller
public class SwaggerTestController {

    /**
     * 测试接口
     * 
     * @return ApiResult 包装的 User 对象
     */
    @ApiOperation("测试接口")  // 描述该接口的功能
    @GetMapping("/test")
    public ApiResult<User> test() {
        // 模拟返回一个成功的响应
        return ApiResult.success(new User("John Doe", "john.doe@example.com"));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  • @Api(tags = "接口文档测试"):用于标识该控制器属于哪个 Swagger 标签,便于在文档中分组展示。
  • @ApiOperation("测试接口"):描述该方法的功能,显示在 Swagger 文档中。

# 五、查看接口文档

完成上述配置和编写测试接口后,可以启动项目并访问 Swagger UI 界面查看生成的 API 文档。

  1. 启动项目: 使用 IDE 或命令行工具启动 Spring 应用。

  2. 访问 Swagger UI: 在浏览器中输入以下地址:

    http://<项目基础路径>/swagger-ui.html
    
    1

    示例:

    http://localhost:8080/swagger-ui.html
    
    1
  3. 查看文档: 成功访问后,您将看到类似以下的界面:

    成功结果

  4. 测试接口: 在 Swagger UI 中,可以看到 接口文档测试 分组下的 测试接口,点击接口名称可以查看详细信息,并可以直接在界面上进行接口测试。

# 六、功能扩展:通过配置文件管理 Swagger 启停

在我们实际开发中,通常希望在开发和测试环境中启用 Swagger,而在生产环境中禁用。为了实现这一需求,可以通过配置文件来管理 Swagger 的启用状态。

# 1. 配置文件中添加 Swagger 开关

在项目的配置文件(如 config.properties)中添加一个配置项,用于控制 Swagger 的启用状态。

# config/config.properties

# Swagger 开关
swagger.enabled=true
1
2
3
4

说明:

  • swagger.enabled:布尔类型,用于控制 Swagger 的启用(true)或禁用(false)。

# 2. 修改 Swagger 配置类以读取配置项

在之前创建的 SwaggerConfig 类中,添加对配置项的读取,并根据配置项决定是否启用 Swagger。

package com.scholar.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Swagger 配置类
 * 
 * 通过配置文件控制 Swagger 的启用与否。
 * 
 * @Author scholar
 * @Date 2022/10/26
 */
@Configuration
@EnableSwagger2
@EnableWebMvc
@ComponentScan(basePackages = {
    "com.xhp.controller"
})
@PropertySource(value = "classpath:config/config.properties", ignoreResourceNotFound = true)
public class SwaggerConfig {

    // 从配置文件中读取 Swagger 启用状态,默认为 true
    @Value("${swagger.enabled:true}")
    private boolean enabled;

    /**
     * 创建 Docket Bean,配置 Swagger 的核心参数
     * 
     * @return Docket 对象
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enabled)  // 根据配置文件决定是否启用 Swagger
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(io.swagger.annotations.ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 配置 API 的基本信息,如标题、描述、联系人等
     * 
     * @return ApiInfo 对象
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("标题:***_接口文档")
                .description("这里是接口文档的详细描述信息")
                .contact(new Contact("scholar", "https://example.com", "scholar@example.com"))
                .version("版本号:2.0")
                .build();
    }

    // Getter 和 Setter 方法

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

说明:

  • @Value("${swagger.enabled:true}"):从配置文件中读取 swagger.enabled 的值,如果未配置则默认为 true。
  • .enable(enabled):根据读取到的配置项决定是否启用 Swagger。

# 3. 切换环境时修改配置文件

根据不同的部署环境,修改 config.properties 中的 swagger.enabled 配置项。

  • 开发/测试环境:

    swagger.enabled=true
    
    1
  • 生产环境:

    swagger.enabled=false
    
    1

注意事项:

  • 确保配置文件在不同环境中正确加载。
  • 部署到生产环境时,务必将 swagger.enabled 设置为 false,以避免暴露内部 API 文档。

# 七、实战案例

# 1. 实体类 (Product.java)

/**
 * 产品实体类
 */
@ApiModel(description = "产品实体,包含产品的基本信息")
public class Product {

    @ApiModelProperty(value = "产品ID", example = "1001", required = true)
    private Long id;

    @ApiModelProperty(value = "产品名称", example = "智能手机", required = true)
    private String name;

    // 构造方法
    public Product() {}

    public Product(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter 和 Setter

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2. 控制器类 (ProductController.java)

/**
 * 产品管理控制器
 */
@Api(tags = "产品管理", description = "产品的获取与创建接口")
@RestController
@RequestMapping("/api/products")
public class ProductController {

    private List<Product> products = new ArrayList<>();

    /**
     * 获取所有产品
     */
    @ApiOperation(value = "获取产品列表", notes = "返回所有产品的信息")
    @ApiResponses({
        @ApiResponse(code = 200, message = "成功获取产品列表"),
        @ApiResponse(code = 500, message = "服务器错误")
    })
    @GetMapping
    public ResponseEntity<List<Product>> getAllProducts() {
        return new ResponseEntity<>(products, HttpStatus.OK);
    }

    /**
     * 创建新产品
     */
    @ApiOperation(value = "创建产品", notes = "根据提供的信息创建新产品")
    @ApiResponses({
        @ApiResponse(code = 201, message = "产品创建成功"),
        @ApiResponse(code = 400, message = "无效的产品信息")
    })
    @ApiParam(value = "产品信息", required = true)
    @PostMapping
    public ResponseEntity<Product> createProduct(@RequestBody Product product) {
        products.add(product);
        return new ResponseEntity<>(product, HttpStatus.CREATED);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  • 实体类:
    • @ApiModel:描述实体类的整体信息。
    • @ApiModelProperty:描述实体类中各个属性的信息。
  • 控制器类:
    • @Api:标识控制器类为 Swagger 的资源,并提供分组和描述信息。
    • @ApiOperation:描述具体的 API 操作。
    • @ApiResponses 和 @ApiResponse:列举接口可能的响应状态。
    • @ApiParam:描述接口方法的参数。
编辑此页 (opens new window)
上次更新: 2025/01/21, 07:18:26
Spring6 - Cache

← Spring6 - Cache

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式