前言
SpringBoot 整合 Swagger
。
实现
理论
Swagger
的作用?
通过简单的配置生成接口的展示页面,把接口的请求参数、返回结果通过可视化的形式展示出来,并且提供了便捷的测试服务。
- 前端程序员可以通过接口展示页面查看需要传递的请求参数和返回的数据格式,不需要后端程序员再编写接口文档了。
- 后端程序员可以通过接口展示页面测试验证自己的接口是否符合预期,降低了开发阶段的调试成本。
什么是 Swagger-UI
:
Swagger-UI
是一套 HTML/CSS/JS
框架,用于渲染 Swagger 文档,以便提供美观的 API 文档界面。
也就是说,Swagger-UI
是 Swagger 提供的一套可视化渲染组件,支持在线导入描述文件和本地部署 UI 项目。
SpringBoot
创建一个 SpringBoot 项目。
pom.xml
在 pom.xml
中导入以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
咦,不是说添加 Swagger 的依赖吗?怎么添加的是 springfox-boot-starter
呢?
这是因为:
Swagger
是一种规范。springfox-swagger
是一个基于 Spring 生态系统的,Swagger 规范的实现。springfox-boot-starter
是springfox
针对SpringBoot
项目提供的一个starter
,简化 Swagger 依赖的导入,否则我们就需要在pom.xml
文件中添加springfox-swagger
、springfox-swagger-ui
等多个依赖。
application.properties
在 application.properties
配置文件中添加如下配置项:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
Swagger配置类
创建如下 SwaggerConfig.java
配置类:
package com.langjialing.swaggerdemo.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
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.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author 郎家岭伯爵
* @time 2023/7/18 9:37
*/
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Bean
public Docket docket() {
Docket docket = new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo()).enable(true)
.select()
//apis: 添加swagger接口提取范围
.apis(RequestHandlerSelectors.basePackage("com.langjialing.swaggerdemo.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("郎家岭伯爵的Swagger文档")
.description("郎家岭伯爵的Swagger Demo项目文档")
.contact(new Contact("郎家岭伯爵", "https://langjialing.com","1830879596@qq.com"))
.version("v1.0")
.build();
}
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}
-
@Configuration
注解通常用来声明一个 Java 配置类,取代了以往的 xml 配置文件,让配置变得更加的简单和直接。 -
@EnableOpenApi
注解表明开启 Swagger。 -
SwaggerConfig
类中包含了一个@Bean
注解声明的方法docket()
,该方法会被 Spring 的AnnotationConfigApplicationContext
或AnnotationConfigWebApplicationContext
类进行扫描,然后添加到 Spring 容器当中。
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
简单描述一下 Swagger 的配置内容:
new Docket(DocumentationType.OAS_30)
,使用 3.0 版本的 Swagger API。OAS 是 OpenAPI Specification 的简称,翻译成中文就是 OpenAPI 说明书,Swagger 遵循的就是这套规范。apiInfo(apiInfo())
,配置 API 文档基本信息,标题、描述、作者、版本等。apis(RequestHandlerSelectors.basePackage("top.codingmore.controller"))
指定 API 的接口范围为 controller 控制器。paths(PathSelectors.any())
指定匹配所有的 URL。
controller层接口
创建如下 controller 接口,测试 Swagger 文档:
package com.langjialing.swaggerdemo.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 郎家岭伯爵
* @time 2023/7/18 10:01
*/
@Api(tags = "测试 Swagger")
@RestController
@RequestMapping("/swagger")
public class SwaggerController {
@ApiOperation("测试")
@RequestMapping("/test")
public String test() {
return "testSwagger";
}
}
-
@Api
注解,用在类上,该注解将控制器标注为一个 Swagger 资源。该注解有 3 个属性:tags
,具有相同标签的 API 会被归在一组内展示。value
:如果tags
没有定义,value
将作为 API 的 tags 使用。description
,已废弃。
-
@ApiOperation
注解,用在方法上,描述这个方法是做什么用的。该注解有 4 个属性:value
操作的简单说明,长度为120个字母,60个汉字。notes
对操作的详细说明。httpMethod
HTTP请求的动作名,可选值有:“GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” 和 “PATCH”。code
默认为200,有效值必须符合标准的HTTP Status Code Definitions
。
-
@RestController
注解,用在类上,是@ResponseBody
和@Controller
的组合注解。如果方法要返回 JSON 的话,可省去@ResponseBody
注解。 -
@RequestMapping
注解,可用在类(父路径)和方法(子路径)上,主要用来定义 API 的请求路径和请求类型。该注解有 6 个属性:value
,指定请求的实际地址method
,指定请求的 method 类型, GET、POST、PUT、DELETE等consumes
,指定处理请求的提交内容类型(Content-Type),例如 application/json, text/htmlproduces
,指定返回的内容类型,仅当 request 请求头中的(Accept)类型中包含该指定类型才返回params
,指定 request 中必须包含某些参数值headers
,指定request中必须包含某些指定的 header 值
访问Swagger文档
启动项目后,在浏览器中输入如下地址可访问 Swagger 文档:
http://localhost:8080/swagger-ui/
总结
SpringBoot 整合 Swagger
。但 Swagger-UI 的界面实在是有点不太优雅,下一篇我们将介绍更好用的 Knife4j
。