Swagger 是一套用于构建、描述和调用 RESTful API 的规范和工具集。核心优势包括:
- 自动生成 API 文档,减少手动编写成本;
- 支持在线调试接口,无需依赖 Postman 等工具;
- 可配置性强,能根据需求定制文档信息;
- 与 Spring 生态无缝集成,上手简单。
- 页面展示:
一、环境准备
1. 核心依赖
本文使用 springdoc-openapi-ui
(而非 Springfox),适配 Spring Boot 2.x 版本,直接引入用户提供的依赖:
XML
<!-- SpringDoc OpenAPI 核心依赖(含 Swagger UI) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
<!-- Spring Security(用于 Swagger 页面认证,可选但推荐) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. 关键版本适配
- Spring Boot 版本:2.x(本文基于 2.6.x 验证)
- SpringDoc 版本:1.6.14(兼容 Spring Boot 2.x,支持 OpenAPI 3.0)
- JDK 版本:1.8+
二、核心配置:从文件到代码
SpringDoc 的配置分为「配置文件(yaml/properties)」和「Java 配置类」两部分,需配合使用才能实现完整功能。
1. 配置文件:自定义 Swagger 行为
在 application.yml
中添加用户提供的 SpringDoc 配置,每一项都附带详细说明,可直接复制使用:
XML
# SpringDoc OpenAPI 核心配置
springdoc:
# Swagger UI 页面配置
swagger-ui:
path: /swagger-ui.html # Swagger UI 访问路径(自定义,如:http://ip:port/上下文/swagger-ui.html)
tags-sorter: alpha # 接口标签(Tag)排序:alpha=字母序,method=定义顺序
operations-sorter: alpha # 同标签下接口排序:alpha=路径字母序,method=HTTP方法序(GET→POST)
# API 文档数据接口(Swagger UI 数据源,返回 JSON)
api-docs:
path: /v3/api-docs # 文档数据路径(如:http://ip:port/上下文/v3/api-docs)
# 接口分组配置(按包/路径筛选接口,避免无关接口混入文档)
group-configs:
- group: default # 分组名称(Swagger UI 顶部可切换,默认一个分组)
paths-to-match: /** # 匹配所有路径的接口(可缩小范围,如:/personInfo/**)
packages-to-scan: com.cetc.ydyl.controller # 扫描的控制器包(只解析该包下的接口)
2. Java 配置类一:OpenAPI 文档元信息(OpenApiConfig)
该类用于定义 Swagger 文档的「基础信息」和「安全方案声明」,告诉文档 "需要什么认证",代码如下:
java
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.Components;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("dev") # 仅在 dev 环境生效(生产环境建议关闭 Swagger)
public class OpenApiConfig {
/**
* 配置 OpenAPI 文档元信息 + 安全方案
*/
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
// 1. 文档基础信息(显示在 Swagger UI 顶部)
.info(new Info()
.title("API文档") // 文档标题
.version("1.0") // 文档版本
.description("项目API文档说明") // 文档描述(可写接口规范、注意事项)
.contact(new Contact().name("ydyl"))) // 联系人(维护者信息)
// 2. 全局安全需求:声明所有接口需通过 "basicAuth" 认证(可按需关闭)
.addSecurityItem(new SecurityRequirement().addList("basicAuth"))
// 3. 定义安全方案:此处为 HTTP Basic 认证(账号密码登录)
.components(new Components()
.addSecuritySchemes("basicAuth", // 安全方案名称(需与上方 SecurityRequirement 对应)
new SecurityScheme()
.type(SecurityScheme.Type.HTTP) // 认证类型:HTTP
.scheme("basic"))); // 认证方式:basic(基础认证)
}
}
3. Java 配置类二:Swagger 安全控制(OpenAPISecurityConfig)
该类基于 Spring Security 实现「实际的认证逻辑」,控制哪些路径需要登录、用什么账号登录,代码如下:
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
@Configuration
@EnableWebSecurity // 启用 Spring Security 安全控制
@Profile("dev") // 仅 dev 环境生效
// 声明 JWT 安全方案(当前项目未使用,属于冗余配置,可删除)
@SecurityScheme(
name = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
public class OpenAPISecurityConfig {
/**
* 配置安全规则:控制路径访问权限
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// 1. Swagger 相关路径必须认证(避免文档暴露)
.antMatchers("/swagger-ui.html", "/v3/api-docs/**").authenticated()
// 2. 其他业务接口允许匿名访问(可根据项目调整为 authenticated())
.anyRequest().permitAll()
.and()
// 3. 启用 HTTP Basic 认证(浏览器弹出账号密码登录框)
.httpBasic()
.and()
// 4. 关闭 CSRF(开发环境简化操作,生产环境需评估)
.csrf().disable();
return http.build();
}
/**
* 配置认证用户:内存存储(生产环境建议用数据库存储)
*/
@Bean
public UserDetailsService userDetailsService() {
// 密码编码器(自动适配 BCrypt 等加密方式)
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
// 定义用户:用户名=ydyl,密码=123456
UserDetails user = User.withUsername("ydyl")
.password(encoder.encode("123456"))
.roles("API_DOCS") // 角色(可用于细粒度权限控制)
.build();
// 内存用户管理器(仅开发环境测试用)
return new InMemoryUserDetailsManager(user);
}
}
注意 :类上的 @SecurityScheme(bearerAuth)
是冗余配置(当前用 Basic 认证,未用 JWT),可删除以精简代码。
三、接口与实体类:用注解完善文档
Swagger 文档的核心是「接口信息」和「参数 / 返回值说明」,需通过注解在控制器和实体类中添加描述,以用户提供的 PersonInfoController
和 PersonInfo
为例。
1. 控制器注解:定义接口信息(PersonInfoController)
控制器类用 @Tag
分组,接口方法用 @Operation
描述功能,代码如下:
java
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Validated;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/personInfo") // 接口基础路径
@Tag(name = "人员-系统人物库") // 接口标签(Swagger UI 左侧分组名称)
public class PersonInfoController {
private final IPersonInfoService onlyService;
// 构造器注入服务(推荐方式,避免字段注入)
public PersonInfoController(IPersonInfoService onlyService) {
this.onlyService = onlyService;
}
/**
* 新增或修改人员信息
*/
@PostMapping("/addOrUpdate")
@Operation(summary = "新增或修改", description = "根据传入的人员信息,不存在则新增,存在则更新")
public BaseResponse<String> addOrUpdate(
@Validated @RequestBody PersonInfo personInfo // @Validated 开启参数校验
) {
String result = onlyService.addOrUpdate(personInfo);
return BaseResponse.success(result);
}
/**
* 根据 ID 删除人员
*/
@PostMapping("/deleteById")
@Operation(summary = "根据ID删除", description = "传入人员ID,逻辑删除对应人员信息")
public BaseResponse<String> deleteById(
@Validated @RequestBody PersonUpdateVo paramVo
) {
String result = onlyService.deleteById(paramVo.getId());
return BaseResponse.success(result);
}
/**
* 分页查询人员信息
*/
@PostMapping("/searchPage")
@Operation(summary = "分页查询", description = "传入查询条件(如手机号、邮箱),返回分页人员列表")
public BaseResponse<Page<PersonInfo>> searchPage(
@RequestBody PersonOnlyParamVo paramVo
) {
Page<PersonInfo> result = onlyService.searchPage(paramVo);
return BaseResponse.success(result);
}
/**
* 导出人员数据
*/
@PostMapping("/export")
@Operation(summary = "导出数据", description = "每天最多导出10次,每次最多20条数据,返回Excel文件")
public BaseResponse<?> exportPerson(
@RequestBody ExportLimitDoc exportLimitDoc,
HttpServletResponse response // 用于输出Excel流
) {
onlyService.exportPerson(exportLimitDoc, response);
return BaseResponse.success();
}
}
2. 实体类注解:定义参数 / 返回值说明(PersonInfo)
实体类用 @Schema
描述类和字段含义,Swagger UI 会自动显示这些说明,代码如下:
java
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.annotations.InnerField;
@Data // Lombok 注解,自动生成 getter/setter
@Schema(description = "人物信息实体类") // 实体类描述(Swagger 中显示)
@Document(indexName = PersonInfo.INDEXNAME, replicas = 0, shards = 1) // Elasticsearch 注解(非 Swagger 相关,无需修改)
public class PersonInfo extends ElasticsearchEntity {
public static final String INDEXNAME = "person_info";
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
@Schema(description = "指纹") // 字段描述
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = {@InnerField(suffix = "keyword", type = FieldType.Keyword)}
)
private String fingerprint;
@Schema(description = "虹膜")
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = {@InnerField(suffix = "keyword", type = FieldType.Keyword)}
)
private String iris;
@Schema(description = "其他生物特征")
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = {@InnerField(suffix = "keyword", type = FieldType.Keyword)}
)
private String otherBiometricFeatures;
@Schema(description = "手机号码")
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = {@InnerField(suffix = "keyword", type = FieldType.Keyword)}
)
private String phoneNumber;
@Schema(description = "邮箱账号")
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = {@InnerField(suffix = "keyword", type = FieldType.Keyword)}
)
private String email;
}
四、访问与测试:验证文档效果
1. 确定访问路径
结合配置文件中的 server.port
、server.servlet.context-path
和 springdoc.swagger-ui.path
,最终访问路径为:
java
http://localhost:9005/ydyl/swagger-ui.html
localhost
:项目部署地址(若部署在服务器,替换为服务器 IP)9005
:用户指定端口ydyl
:应用上下文路径swagger-ui.html
:Swagger UI 自定义路径
2. 登录认证
访问上述路径后,浏览器会弹出「基础认证」对话框,输入配置的账号密码:
- 用户名:
ydyl
- 密码:
123456
(原始密码,非加密后的字符串)
3. 文档使用
登录成功后,即可看到完整的 Swagger 文档界面:
- 左侧标签 :显示
人员-系统人物库
(对应@Tag
注解),点击可展开所有接口; - 接口详情 :每个接口显示
summary
和description
(对应@Operation
注解),可查看请求参数(自动显示PersonInfo
字段的@Schema
说明); - 在线调试:点击接口右侧的「Try it out」,输入参数后点击「Execute」,即可直接调用接口并查看返回结果。
