11---
2+ title : Spring Boot整合Knife4j,美化强化丑陋的Swagger
23category :
34 - Java企业级开发
45tag :
5- - 辅助工具/轮子
6+ - Spring Boot
67---
78
89
9- # knife4j:一款界面更炫酷的API文档生成神器
10-
11- 一般在使用 Spring Boot 开发前后端分离项目的时候,都会用到 Swagger。Swagger 是一个规范和完整的框架,用于生成、描述、调试和可视化 RESTful 风格的 Web API 服务框架。
10+ 一般在使用 Spring Boot 开发前后端分离项目的时候,都会用到 [ Swagger] ( https://tobebetterjavaer.com/springboot/swagger.html ) (戳链接详细了解)。
1211
1312但随着系统功能的不断增加,接口数量的爆炸式增长,Swagger 的使用体验就会变得越来越差,比如请求参数为 JSON 的时候没办法格式化,返回结果没办法折叠,还有就是没有提供搜索功能。
1413
15- 刚好最近发现 Knife4j 弥补了这些不足,赋予了 Swagger 更强的生命力,于是就来给大家安利一波 。
14+ 今天我们介绍的主角 Knife4j 弥补了这些不足,赋予了 Swagger 更强的生命力和表现力 。
1615
17- ### 一、 关于 Knife4j
16+ ### 关于 Knife4j
1817
1918Knife4j 的前身是 swagger-bootstrap-ui,是 springfox-swagger-ui 的增强 UI 实现。swagger-bootstrap-ui 采用的是前端 UI 混合后端 Java 代码的打包方式,在微服务的场景下显得非常臃肿,改良后的 Knife4j 更加小巧、轻量,并且功能更加强大。
2019
@@ -26,7 +25,7 @@ swagger-bootstrap-ui 增强后的样子长下面这样。单纯从直观体验
2625
2726![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-2.png )
2827
29- 改良后的 Knife4j 不仅在界面上更加优雅、炫酷,功能上也更加强大:后端 Java 代码和前端 UI 模块分离了出来,在微服务场景下更加灵活;更提供了专注于 Swagger 的增强解决方案。
28+ 那改良后的 Knife4j 不仅在界面上更加优雅、炫酷,功能上也更加强大:后端 Java 代码和前端 UI 模块分离了出来,在微服务场景下更加灵活;还提供了专注于 Swagger 的增强解决方案。
3029
3130![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-3.png )
3231
@@ -36,38 +35,40 @@ swagger-bootstrap-ui 增强后的样子长下面这样。单纯从直观体验
3635
3736码云地址:
3837
39- > https://gitee.com/xiaoym/knife4j
38+ > [ https://gitee.com/xiaoym/knife4j ] ( https://gitee.com/xiaoym/knife4j )
4039
4140示例地址:
4241
43- > https://gitee.com/xiaoym/swagger-bootstrap-ui-demo
42+ > [ https://gitee.com/xiaoym/swagger-bootstrap-ui-demo ] ( https://gitee.com/xiaoym/swagger-bootstrap-ui-demo )
4443
45- ### 二、 整合 Swagger
44+ ### 整合 Knife4j
4645
47- 为了对比 Knife4j 和 Swagger,我们先来整合体验一把 Swagger 。
46+ Knife4j 完全遵循了 Swagger 的使用方式,所以可以无缝切换 。
4847
49- 第一步,在 pom.xml 中添加 springfox 的官方 Swagger 依赖:
48+ 第一步,在 pom.xml 文件中添加 Knife4j 的依赖( ** 不需要再引入 springfox-boot-starter ** 了,因为 Knife4j 的 starter 里面已经加入过了)。
5049
5150```
5251<dependency>
53- <groupId>io.springfox</groupId>
54- <artifactId>springfox-boot-starter</artifactId>
55- <version>3.0.0</version>
52+ <groupId>com.github.xiaoymin</groupId>
53+ <artifactId>knife4j-spring-boot-starter</artifactId>
54+ <!--在引用时请在maven中央仓库搜索3.X最新版本号-->
55+ <version>3.0.2</version>
5656</dependency>
5757```
5858
59- 第二步,添加 Swagger 的 Java 配置,只需要配置基本的 API 信息和需要扫描的类路径即可 。
59+ 第二步,配置类 SwaggerConfig 还是 Swagger 时期原来的配方 。
6060
6161``` java
6262@Configuration
63+ @EnableOpenApi
6364public class SwaggerConfig {
6465 @Bean
6566 public Docket docket () {
6667 Docket docket = new Docket (DocumentationType . OAS_30 )
6768 .apiInfo(apiInfo()). enable(true )
6869 .select()
6970 // apis: 添加swagger接口提取范围
70- .apis(RequestHandlerSelectors . basePackage(" com .codingmore.controller" ))
71+ .apis(RequestHandlerSelectors . basePackage(" top .codingmore.controller" ))
7172 .paths(PathSelectors . any())
7273 .build();
7374
@@ -76,88 +77,100 @@ public class SwaggerConfig {
7677
7778 private ApiInfo apiInfo () {
7879 return new ApiInfoBuilder ()
79- .title(" 编程猫学习网站的 admin 管理端 API " )
80- .description(" codingmore " )
81- .contact(new Contact (" 沉默王二&石磊 " , " https://tobebetterjavaer.com " , " 983436076@qq .com" ))
82- .version(" 1 .0" )
80+ .title(" 编程猫实战项目笔记 " )
81+ .description(" 编程喵是一个 Spring Boot+Vue 的前后端分离项目 " )
82+ .contact(new Contact (" 沉默王二" , " https://codingmore.top " , " www.qing_gee@163 .com" ))
83+ .version(" v1 .0" )
8384 .build();
8485 }
8586}
8687```
8788
88- 第二步,访问 API 文档,访问地址如下所示:
89-
90- > http://localhost:9002/swagger-ui/
91-
92- 在项目路径后面添加上 ` swagger-ui ` 就可以了。
93-
94- ![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-4.png )
95-
96- 在 Controller 类中,可以看到常见的 Swagger 注解 @Api 和 @ApiOperation :
89+ 第三步,新建测试控制器类 Knife4jController.java:
9790
9891``` java
99- @Controller
100- @Api ( tags = " 文章 " )
101- @RequestMapping (" /posts " )
102- public class PostsController {
103- @RequestMapping ( value = " /delete " , method = RequestMethod . GET )
104- @ResponseBody
105- @ApiOperation ( " 删除 " )
106- public ResultObject< String > delete ( long postsId ) {
107- return ResultObject . success(postsService . removePostsById(postsId) ? " 删除成功 " : " 删除失败 " ) ;
92+ @Api ( tags = " 测试 Knife4j " )
93+ @RestController
94+ @RequestMapping (" /knife4j " )
95+ public class Knife4jController {
96+
97+ @ApiOperation ( " 测试 " )
98+ @RequestMapping ( value = " /test " , method = RequestMethod . POST )
99+ public String test ( ) {
100+ return " 沉默王二又帅又丑 " ;
108101 }
109102}
110103```
111104
112- - @Api 注解用在类上,该注解将一个 Controller 类标记位一个 Swagger 资源(API)。默认情况下,Swagger 只会扫描解析具有 @Api 注解的类。
113-
114- - @ApiOperation 注解用在方法上,该注解在指定的方法上,对一个方法进行描述。
115-
116- Swagger 还有很多其他的注解,比如说 @ApiParam 、@ApiResponses 等等,这里就不再一一说明。
117-
118- ### 三、整合 Knife4j
105+ 第四步,由于 springfox 3.0.x 版本 和 Spring Boot 2.6.x 版本有冲突,所以还需要先解决这个 bug,一共分两步(在[ Swagger] ( https://tobebetterjavaer.com/springboot/swagger.html ) 那篇已经解释过了,这里不再赘述,但防止有小伙伴在学习的时候再次跳坑,这里就重复一下步骤)。
119106
120- Knife4j 完全遵循了 Swagger 的使用方式,所以可以无缝切换。
121-
122- 第一步,在 pom.xml 文件中添加 Knife4j 的依赖(** 不需要再引入 springfox-boot-starter** )。
107+ 先在 application.yml 文件中加入:
123108
124109```
125- <dependency>
126- <groupId>com.github.xiaoymin</groupId>
127- <artifactId>knife4j-spring-boot-starter</artifactId>
128- <!--在引用时请在maven中央仓库搜索3.X最新版本号-->
129- <version>3.0.2</version>
130- </dependency>
110+ spring:
111+ mvc:
112+ path match:
113+ matching-strategy: ANT_PATH_MATCHER
131114```
132115
133- 第二步,在 Java 配置类上添加 @ EnableOpenApi 注解,开启 Knife4j 增强功能。
116+ 再在 SwaggerConfig.java 中添加:
134117
135118``` java
136- @Configuration
137- @EnableOpenApi
138- public class SwaggerConfig {}
119+ @Bean
120+ public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
121+ return new BeanPostProcessor () {
122+
123+ @Override
124+ public Object postProcessAfterInitialization (Object bean , String beanName ) throws BeansException {
125+ if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider ) {
126+ customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
127+ }
128+ return bean;
129+ }
130+
131+ private <T extends RequestMappingInfoHandlerMapping > void customizeSpringfoxHandlerMappings (List<T > mappings ) {
132+ List<T > copy = mappings. stream()
133+ .filter(mapping - > mapping. getPatternParser() == null )
134+ .collect(Collectors . toList());
135+ mappings. clear();
136+ mappings. addAll(copy);
137+ }
138+
139+ @SuppressWarnings (" unchecked" )
140+ private List<RequestMappingInfoHandlerMapping > getHandlerMappings (Object bean ) {
141+ try {
142+ Field field = ReflectionUtils . findField(bean. getClass(), " handlerMappings" );
143+ field. setAccessible(true );
144+ return (List<RequestMappingInfoHandlerMapping > ) field. get(bean);
145+ } catch (IllegalArgumentException | IllegalAccessException e) {
146+ throw new IllegalStateException (e);
147+ }
148+ }
149+ };
150+ }
139151```
140152
141- 第三步,重新运行 Spring Boot 项目,访问 API 文档,查看效果 。
153+ 以上步骤均完成后,开始下一步,否则要么项目启动的时候报错,要么在文档中看不到测试的文档接口 。
142154
143- > 访问地址: http://localhost:9002/doc.html
155+ 第五步,运行 Spring Boot 项目,浏览器地址栏输入以下地址访问 API 文档,查看效果。
144156
145- ![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-5.png )
157+ > 访问地址(和 Swagger 不同): [ http://localhost:8080/doc.html ] ( http://localhost:8080/doc.html )
146158
147- 如果项目中加了权限认证的话,记得给 Knife4j 添加白名单。我的项目用的是 SpringSecurity,所以需要在 application.yml 文件中添加。
148159
149- ```
150- secure:
151- ignored:
152- urls: #安全路径白名单
153- - /doc.html
154- - /swagger-ui/**
155- - /swagger/**
156- - /swagger-resources/**
157- - /**/v3/api-docs
158- ```
160+ ![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-0a9eb2b1-bace-4f47-ace9-8a5f9f280279.png )
161+
162+ 是不是比 Swagger 简洁大方多了?如果想测试接口的话,可以直接点击接口,然后点击「测试」,点击发送就可以看到返回结果了。
163+
164+ ![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-16b1b553-1667-4222-9f29-2e5dfc8917a0.png )
165+
166+ ### Knife4j 的功能特点
167+
168+ 编程喵🐱实战项目中已经整合好了 Knife4j,在本地跑起来后,就可以查看所有 API 接口了。编程喵中的管理端(codingmore-admin)端口为 9002,启动服务后,在浏览器中输入 [ http://localhost:9002/doc.html ] ( http://localhost:9002/doc.html ) 就可以访问到了。
169+
170+ ![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-3cfbf598-b94a-4081-aab3-06af1eef612c.png )
171+
172+ 简单来介绍下 Knife4j 的 功能特点:
159173
160- ### 四、Knife4j 的功能特点
161174
162175** 1)支持登录认证**
163176
@@ -207,18 +220,48 @@ Swagger 是没有搜索功能的,当要测试的接口有很多的时候,当
207220
208221目前支持搜索接口的地址、名称和描述。
209222
210- ### 五、 尾声
223+ ### 尾声
211224
212225除了我上面提到的增强功能,Knife4j 还提供了很多实用的功能,大家可以通过官网的介绍一一尝试下,生产效率会提高不少。
213226
214- > https://doc.xiaominfo.com/knife4j/documentation/enhance.html
227+ > [ https://doc.xiaominfo.com/knife4j/documentation/enhance.html ] ( https://doc.xiaominfo.com/knife4j/documentation/enhance.html )
215228
216229![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/gongju/knife4j-15.png )
217230
218231如果项目中之前使用过 Swagger 生成接口文档,切换到 Knife4j 可以说是非常的丝滑,只需要两步:
219232
220233- 在 pom.xml 文件中把 ` springfox-boot-starter ` 替换为 ` knife4j-spring-boot-starter ` ;
221- - 访问地址由原来的 ` http://${host}:${port}/swagger-ui.html ` 切换到 ` http://${host}:${port}/doc.html ` ,如果有权限限制的话,记得开白名单。
234+ - 访问地址由原来的 ` http://${host}:${port}/swagger-ui.html ` 切换到 ` http://${host}:${port}/doc.html ` ,如果有权限限制的话,记得开白名单。比如说,编程喵整合了 SpringSecurity,所以需要在 application.yml 文件中放开 Swagger 和 Knife4j 的访问后缀。
235+
236+
237+ ```
238+ # 自定义类 ignoreConfig,URL 的白名单
239+ secure:
240+ ignored:
241+ urls: #安全路径白名单
242+ - /doc.html
243+ - /swagger-ui/**
244+ - /swagger/**
245+ - /swagger-resources/**
246+ - /**/v3/api-docs
247+ - /**/*.js
248+ - /**/*.css
249+ - /**/*.png
250+ - /**/*.ico
251+ - /webjars/springfox-swagger-ui/**
252+ - /actuator/**
253+ - /druid/**
254+ - /users/login
255+ - /users/register
256+ - /users/info
257+ - /users/logout
258+ - /minio/upload
259+ ```
260+
261+ ### 源码路径
262+
263+ > - 编程喵:[ https://github.com/itwanger/coding-more ] ( https://github.com/itwanger/coding-more )
264+ > - codingmore-knife4j:[ https://github.com/itwanger/codingmore-learning ] ( https://github.com/itwanger/codingmore-learning/tree/main/codingmore-knife4j )
222265
223266
224267![ ] ( http://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xingbiaogongzhonghao.png )
0 commit comments