前言

这篇文章中我的项目是从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/

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐