【实战场景】SpringBoot整合Swagger快速实现
- 开篇词:
- 干货篇:
- 一. Swagger简介
- 二. SpringBoot整合Swagger3环境搭建
- 1. 引入maven依赖
- 2. YML配置
- 3. Swagger配置类
- 4. Swagger分组配置
- 三. Swagger 常用注解配置
- 1. @Api
- 2. @ApiOperation
- 3. @ApiParam
- 4. @ApiModel 和 @ApiModelProperty
- 5. @ApiResponses 和 @ApiResponse
- 6. @ApiImplicitParams与@ApiImplicitParam 参数描述
- 四. Swagger 接口文档导出/更改UI
- 五. Swagger 整合常见问题
- 1. 版本兼容性问题
- 2. 配置错误
- 3. 注解使用不当
- 4. 访问Swagger UI时出现错误
- 5. Swagger文档不更新
- 总结
- 我是杰叔叔,一名沪漂的码农,下期再会!
开篇词:
最近新启用了一个微服务需要接入swagger,下面就一起探讨下接入过程吧
干货篇:
一. Swagger简介
- 开源工具集: Swagger是一个包含多种工具和库的开源项目,用于支持RESTful API的设计、开发、文档化和测试。
- 标准化: Swagger通过Swagger Specification(现为OpenAPI Specification)定义了一套标准化的API描述格式,使得API的文档和描述具有一致性和可重用性。
- 多版本: 在SpringBoot中,Spring 基于Swagger 的标准/规范,开发了一套适用于Spring生态的接口工具框架 Springfox-swagger ,Swagger发展到今天,已经有2.x和3.x两种主流的大版本,同样Springfox-swagger也有两种相应的版本,两种版本略有不同,我们这里主要讲Swagger3的整合与使用。
二. SpringBoot整合Swagger3环境搭建
1. 引入maven依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
2. YML配置
spring boot 2.6.x或更高版本集成Swagger时,直接运行会出现异常信息报错(空指针),主要原因是:Spring Boot 2.6及 更高版本使用的默认路径匹配规则是PathPatternMatcher,而Springfox使用的路径匹配是基于AntPathMatcher的。
所以这里需要更改一下SpringBoot配置。
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
3. Swagger配置类
配置类中各部分配置的含义都已经通过注释说明
@Configuration //声明配置类
@EnableOpenApi //开启swagger支持
public class SwaggerConfig {
/**
* Docket类是Swagger的配置类,要自定义修改Swagger的默认配置信息,我们需要覆盖该对象
* @return
*/
@Bean
public Docket docket(){
//1.以OAS_30标准构建Docket配置类
return new Docket(DocumentationType.OAS_30)
//2.配置Swagger接口文档基本信息apiInfo
.apiInfo(apiInfo())
//3.select方法开启配置扫描接口的Builder
.select()
//4.指定要扫描/维护接口文档的包(否则就全部扫描)
.apis(RequestHandlerSelectors.basePackage("com.example.bootswagger.controller"))
//5.路径过滤:该Docket-UI展示时,只展示指定路径下的接口文档(any表示都展示)
.paths(PathSelectors.any())
.build();
}
/**
* 配置 Swagger 接口文档的基本信息
* @return
*/
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
//1.接口文档标题
.title("SpringBoot整合Swagger")
//2.接口文档描述内容
.description("这里是SpringBoot整合Swagger的详细信息......,包括...")
//3.项目文档迭代版本
.version("9.0")
//4.主要联系人信息(姓名name,个人主页url,邮箱email)
.contact(new Contact("阿安","www.baidu.com","1436218372@qq.com"))
//5.相关许可证信息
.license("The CSDN License")
//6.相关许可证链接
.licenseUrl("www.baidu.com")
//7.返回构建的ApiInfo对象
.build();
}
}
配置完成后启动SpringBoot项目,访问 http://localhost:8080/swagger-ui/index.html 或 http://localhost:8080/swagger-ui/ 即可看到生成的接口文档。
4. Swagger分组配置
在Swagger实现中,一个Docket配置类对应一组文档配置,既然要进行分组,那么分几组我们就要分别配置几个相应的Docket对象,然后通过groupName()方法配置分组信息(名称)。
@Configuration //声明配置类
@EnableOpenApi //开启swagger支持
public class SwaggerConfig {
/**
* 配置分组文档 docketA :该部分文档由王五负责,主要涉及UserController相应接口的开发,对应url为 /user/**
* @return
*/
@Bean
public Docket docketA(){
//1.以OAS_30文档标准构建Docket配置类
return new Docket(DocumentationType.OAS_30)
//2.配置Swagger接口文档基本信息apiInfoA
.apiInfo(apiInfoA())
//3.配置文档分组-名称
.groupName("docketA")
//4.select方法开启配置扫描接口的Builder
.select()
//5.指定要扫描/维护接口文档的包:bootswagger.controller
.apis(RequestHandlerSelectors.basePackage("com.example.bootswagger.controller"))
//6.指定路径过滤规则:docketA只展示 /user/** 路径下的接口描述(配合包扫描)
.paths(PathSelectors.ant("/user/**"))
.build();
}
/**
* 配置分组文档 docketB :该部分文档由李四负责,主要涉及AdminController相应接口的开发,对应url为 /admin/**
* @return
*/
@Bean
public Docket docketB(){
//1.以OAS_30文档标准构建Docket配置类
return new Docket(DocumentationType.OAS_30)
//2.配置Swagger接口文档基本信息apiInfoB
.apiInfo(apiInfoB())
//3.配置文档分组-名称
.groupName("docketB")
//4.select方法开启配置扫描接口的Builder
.select()
//5.指定要扫描/维护接口文档的包:bootswagger.controller
.apis(RequestHandlerSelectors.basePackage("com.example.bootswagger.controller"))
//6.指定路径过滤规则:docketA只展示 /user/** 路径下的接口描述(配合包扫描)
.paths(PathSelectors.ant("/admin/**"))
.build();
}
/**
* 配置 文档A 的基本信息
* @return
*/
private ApiInfo apiInfoA(){
return new ApiInfoBuilder()
//1.接口文档标题
.title("文档A:SpringBoot整合Swagger")
//2.接口文档描述内容
.description("这里是SpringBoot整合Swagger的详细信息......,包括...")
//3.项目文档迭代版本
.version("9.0")
//4.主要联系人信息(姓名name,个人主页url,邮箱email)
.contact(new Contact("王五","www.baidu.com","1436218372@qq.com"))
//7.返回构建的ApiInfo对象
.build();
}
/**
* 配置 文档B 的基本信息
* @return
*/
private ApiInfo apiInfoB(){
return new ApiInfoBuilder()
//1.接口文档标题
.title("文档B:SpringBoot整合Swagger")
//2.接口文档描述内容
.description("这里是SpringBoot整合Swagger的详细信息......,包括...")
//3.项目文档迭代版本
.version("2.0")
//4.主要联系人信息(姓名name,个人主页url,邮箱email)
.contact(new Contact("李四","www.baidu.com","1436218372@qq.com"))
//7.返回构建的ApiInfo对象
.build();
}
}
三. Swagger 常用注解配置
Swagger(或现在更常用的OpenAPI规范)提供了许多注解,用于在Java代码中以声明性方式定义API的元数据。这些注解被Swagger库(如Springfox用于Swagger 2.x或SpringDoc用于OpenAPI 3.x)扫描和处理,以生成API文档。以下是一些常用的Swagger注解及其配置示例:
1. @Api
在Swagger 2.x中,@Api注解用于标记一个类作为Swagger文档中的一个资源(通常是一个RESTful Controller)。在OpenAPI 3.x中,这个注解的使用已经较少,因为SpringDoc等库提供了自动扫描Controller的机制。
Swagger 2.x 示例:
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Api(value = "用户接口", tags = {"用户管理"})
@RestController
@RequestMapping("/users")
public class UserController {
// ...
}
2. @ApiOperation
@ApiOperation注解用于描述一个具体的方法操作。你可以用它来指定方法的简短描述、HTTP方法、是否产生响应等。
示例:
import io.swagger.annotations.ApiOperation;
@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户详细信息", httpMethod = "GET")
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
// ...
}
3. @ApiParam
@ApiParam注解用于描述方法的参数。它提供了参数的名称、是否必需、数据类型以及描述等信息。
示例:
import io.swagger.annotations.ApiParam;
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@ApiParam(value = "搜索关键字", required = true) @RequestParam String keyword) {
// ...
}
4. @ApiModel 和 @ApiModelProperty
@ApiModel用于描述一个返回的对象(或请求的参数对象)。@ApiModelProperty则用于描述对象中的一个属性。
示例:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(description = "用户信息")
public class User {
@ApiModelProperty(value = "用户ID", example = "12345")
private Long id;
@ApiModelProperty(value = "用户名", required = true)
private String username;
// getters and setters
}
5. @ApiResponses 和 @ApiResponse
@ApiResponses用于列出一个方法可能返回的所有响应。@ApiResponse则用于描述其中的一个响应,包括HTTP状态码、描述以及可能返回的对象。
示例:
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ApiResponse;
@ApiResponses(value = {
@ApiResponse(code = 200, message = "请求成功", response = User.class),
@ApiResponse(code = 404, message = "未找到资源")
})
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
// ...
}
6. @ApiImplicitParams与@ApiImplicitParam 参数描述
@ApiImplicitParams(list=[ ]):该注解作用在接口方法上,是ApiImplicitParam的列表
@ApiImplicitParam(name="参数名称",value = "参数说明",defaultValue = "参数默认值",dataType = "数据类型"):该注解作用于ApiImplicitParams列表内,用于对方法上的参数进行描述说明。
@RestController
@RequestMapping("/user")
@Api(tags = "用户请求处理Controller")
public class UserController {
@ApiOperation(value = "用户登陆方法",notes = "<span style='color:red;'>描述:</span> 用来执行用户登录方法的接口",response = ResultVo.class)
@RequestMapping(value = "/login",method = RequestMethod.GET)
@ApiImplicitParams({
@ApiImplicitParam(name="username",value = "用户名",defaultValue = "admin",dataType = "String"),
@ApiImplicitParam(name="userInfo",value = "用户信息",defaultValue = "nothing",dataType = "String")
})
public ResultVo loginUser(String userName,String userInfo){
System.out.println(userName);
System.out.println(userInfo);
ResultVo resultVo = new ResultVo();
resultVo.setCode(1);
resultVo.setMessage("Login SUCCESS");
return resultVo;
}
}
注意:参数使用@RequestBody时,@ApiImplicitParam的type就不要使用body了,二者相互冲突,可以使用 @ApiParam 处理。而且不使用@RequestBody时,@ApiImplicitParam将参数统一附加到地址url;使用@RequestBody后,不再附加。
四. Swagger 接口文档导出/更改UI
Swagger原生官方依赖不提供文档导出功能,只能网页在线查看。所以要实现接口文档导出,我们可以整合第三方Swagger-UI界面提供的文档导出功能(主要)
bootstrap-UI
Layui-UI
mg-UI
knife4j
例如bootstrap-UI,引入依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
五. Swagger 整合常见问题
Swagger整合Spring Boot的过程中,开发者可能会遇到一些常见问题。这些问题通常与版本兼容性、配置错误、注解使用不当等方面有关。以下是一些常见的问题及其解决方案:
1. 版本兼容性问题
- 问题描述:
在整合Swagger时,由于Spring Boot和Swagger的版本不匹配,可能会出现启动失败、文档无法生成等问题。 - 解决方案:
确保使用的Swagger版本与Spring Boot版本兼容。例如,Spring Boot 2.7及以上版本推荐使用Swagger 3.x(通过SpringDoc OpenAPI库实现)而非Swagger 2.x。
对于Swagger 2.x,建议使用Spring Boot 2.6及以下版本。
查看Maven官方仓库或相关文档,获取版本兼容性的详细信息。
2. 配置错误
- 问题描述:
配置文件中的错误设置(如application.yml或application.properties)可能导致Swagger无法正常工作。 - 解决方案:
检查配置文件中的Swagger相关配置是否正确。例如,确保Swagger的扫描包路径、端口号、上下文路径等设置正确。
对于Spring Boot 2.6及以上版本,如果使用了Swagger 3.x(通过SpringDoc OpenAPI),需要添加相应的配置注解(如@EnableOpenApi)和依赖。
如果遇到路径匹配问题(如Spring Boot 2.6.X引入的新路径匹配策略导致的与Springfox的不兼容),可以在配置文件中设置spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER。
3. 注解使用不当
- 问题描述:
在Controller或Model类中使用Swagger注解时,如果注解使用不当(如位置错误、属性设置错误等),可能会导致生成的API文档不完整或错误。 - 解决方案:
确保Swagger注解被正确放置在类、方法或参数上。
检查注解的属性设置是否正确,如@ApiOperation的summary、description等属性。
对于复杂的Model类,使用@ApiModel和@ApiModelProperty等注解来详细描述其结构和属性。
4. 访问Swagger UI时出现错误
- 问题描述:
在浏览器中输入Swagger UI的访问地址后,可能出现404错误、页面无法加载或显示错误信息等。 - 解决方案:
确保Swagger UI的访问地址正确。对于Swagger 2.x,通常是/swagger-ui.html;对于Swagger 3.x(通过SpringDoc OpenAPI),可能是/swagger-ui/index.html。
检查Spring Boot应用是否已正确启动并正在监听预期的端口。
检查是否有安全配置(如Spring Security)阻止了对Swagger UI的访问。如果是,请添加相应的权限配置以允许访问。
5. Swagger文档不更新
- 问题描述:
在修改Controller或Model类后,生成的Swagger文档没有更新以反映这些更改。 - 解决方案:
确保在修改代码后重新编译并重启Spring Boot应用。
检查是否有缓存机制(如浏览器缓存或服务器缓存)影响了文档的更新。尝试清除缓存后再次访问。
总结
总结
对于OpenAPI 3.x(通常与SpringDoc一起使用),注解的名称和某些属性可能有所不同,但基本概念是相似的。
某些Swagger 2.x的注解在OpenAPI 3.x中可能没有直接对应的注解,因为OpenAPI 3.x提供了更丰富的功能和更清晰的语义。
在实际项目中,应根据所使用的库(Springfox或SpringDoc)和OpenAPI规范版本(2.x或3.x)来选择合适的注解和配置方式。
其他坑留着大家一起踩完,一起分享吧~~