【原创】Knife4j从2.x升级到4.x版本升级方案和措施,并解决SpringBoot3.x无法显示knife4j文档问题,报No static resource swagger-resources
通过这篇文章介绍了Knife4j从2.0.9升级到4.4.0的步骤,并详细介绍了升级方法,还有遇到的故障排除
前言
这篇文章中我的项目是从Knife4j2.0.9升级到4.4.0。起因是群里有人说swagger打不开了,说是Fastjson转换器导致的问题,我就不信这个邪了,因为我的项目中也存在这个东西,也没听说会让swagger打不开。结果我运行项目后发现swagger还真打不开了!
报错内容为:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource swagger-resources.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
看了一下knife4j的文档才发现原来是版本不匹配了,SpringBoot3.x版本必须匹配Knife4j 4.x版本,我也确实把SpringBoot版本从2.x升级到3.4.2了。
这里我就说一下如何将Knife4j从2.0.9升级到4.4.0。因为我这是我自己的项目,且用到的Knife4j的功能并不是很多,如果有疏漏请大家补充
pom引用
<!-- 原来的 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.9</version>
</dependency>
<!-- 现在的 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
pom引用需要改为新版本的,就连maven坐标都变了,这是大改。
配置文件application.yaml
#knife4j配置信息
knife4j:
# 是否开启增强模式,建议必须开启
enable: true
setting:
language: zh_cn
# production改为true则会关闭knife4j和swagger所有文档
production: false
## 开启Swagger的Basic认证功能,默认是false
basic:
enable: true
## Basic认证用户名
username: admin
## Basic认证密码
password: 123456
# springdoc-openapi项目配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
enabled: true
api-docs:
path: /v3/api-docs
enabled: true
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: 改为你的包名
注意,如果要彻底关闭knife4j用于生产环境,请改production的值为true,而不是将knife4j的enable改为false!
根据自己的情况修改配置文件
ControllerAdvice
没错!被这个注解修饰的类也需要修改,需要添加上@Hidden,来自包:import io.swagger.v3.oas.annotations.Hidden
@Hidden
@ControllerAdvice
class ProjectExceptionHandler(
如果不加的话进入doc.html会报错,内容为:
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.NoSuchMethodError: 'void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1103)
at
Caused by: java.lang.NoSuchMethodError: 'void org.springframework.web.method.ControllerAdviceBean.<init>(java.lang.Object)'
at org.springdoc.core.service.GenericResponseService.lambda$getGenericMapResponse$8(GenericResponseService.java:702)
注解
真正的修改大头来了,OpenAPI V3的对应的注解和之前swagger2的注解完全不同,这可要了老命咯
注解对比
旧注解(Swagger2) | 新注解(OpenAPI3) | 功能说明 |
@Api(类) | @Tag(类) | 定义接口分组或模块名称 |
@ApiOperation(方法) | @Operation(方法) | 描述接口功能 |
@ApiModelProperty(字段) | @Schema(字段) | 描述模型属性 |
@ApiParam(参数) | @Parameter(参数) | 描述请求参数 |
@ApiResponse(响应) | @ApiResponse(响应) | 描述接口响应(名称不变,包路径变化) |
@ApiModel(类) | @Schema(类) | 描述模型类 |
可以说是所有注解都改了,以至于项目中所有接口相关的都要改一遍,关键是注解里面的参数也变了,原来用value的,现在换成了title/name等等
全局批量替换
建议将这些注解和包引入全部全局批量替换一下,从字多的换到字少的
import io.swagger.annotations.ApiModelProperty
import io.swagger.v3.oas.annotations.media.Schema
@ApiModelProperty(value
@Schema(title
import io.swagger.annotations.ApiModel
import io.swagger.v3.oas.annotations.media.Schema
@ApiModel(
@Schema(name =
import io.swagger.annotations.ApiOperation
import io.swagger.v3.oas.annotations.Operation
@ApiOperation(value =
@Operation(summary =
import io.swagger.annotations.ApiParam
import io.swagger.v3.oas.annotations.Parameter
@ApiParam
@Parameter
import io.swagger.annotations.Api
import io.swagger.v3.oas.annotations.tags.Tag
以上是我批量替换的内容,4行中第1行和第3行是原来的,分别替换为第2行和第4行
Api注解替换
还剩最后一个Api注解,我原来写的是@Api(tags = [AccountController.moduleName], value = AccountController.moduleName),但是现在要写@Tag(name = AccountController.moduleName),其中XXXController是动态的,没法全局批量替换,这里采用代码替换:
fun main() {
val projectRoot = File("你的项目路径") // 替换为实际项目路径
val fileExtension = "Controller.kt"
projectRoot.walk()
.filter { it.isFile && it.name.endsWith(fileExtension) }
.forEach { file ->
val className = file.nameWithoutExtension // 提取类名(如:UserController)
val originalContent = file.readText(Charset.defaultCharset())
if (originalContent.contains("@Api")) {
val start = originalContent.indexOf("@Api")
val end = originalContent.indexOf(")", start)
val newContent = originalContent.substring(0, start) +
"@Tag(name = $className.moduleName)" +
originalContent.substring(end+1)
if (originalContent != newContent) {
file.writeText(newContent)
println("已更新文件:${file.absolutePath}")
}
}
}
}
Kotlin代码相当简洁,连遍历递归都不用了
去掉基类注解
【转载】【问题记录】解决Knife4j 4.x版本在SpringBoot3.x版本中返回字段类型包含泛型,但是api文档中不显示泛型中字段的问题-CSDN博客
可以看我这篇文章,如果基类中存在@Schema注解,则其中的泛型会无法解析出正确的类型,只会显示出object类型
增加favicon.ico
如果没有favicon.ico进入doc.html后会报错,内容为:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
虽然不影响页面显示,但是后端会提示报错信息,建议在resources下建立static目录,放入一个favicon.ico文件
完成效果
完成效果如下:
结语
对于我这个个人项目来说从Knife4j2.0.9升级到4.4.0就这些步骤,如果什么需要补充的地方,欢迎大家来评论区评论,或者来我的Q群(170618278)交流也行。也是没想到这个升级改动这么大,花费了我很长时间解决问题。
Knife4j的文档还是建议查看官网:https://doc.xiaominfo.com/docs/
更多推荐
所有评论(0)