目录

如何在springboot3.x的版本使用knife4j?

解决knife4j无法访问

以下是一些关于怎么找到这个解决办法(微服务项目debug)的经验(吐槽)分享


如何在springboot3.x的版本使用knife4j?

参考springboot版本:3.2.4

相比于springboot2.x版本,在3.x版本使用knife4j将有较大的不同

关于使用的官方文档:快速开始 | Knife4j (xiaominfo.com)

        1. 首先,对于需要使用knife4j的模块,在其pom.xml中添加依赖:

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

        2. 然后在模块下的src/main/resources/application.yml文件中配置属性

需要且仅需要更改packages-to-scan:的值,改为你模块下controller包的路径

# springdoc-openapi项目配置
springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.xiaominfo.knife4j.demo.web    #这里换成你模块下controller包的路径

# knife4j的增强配置,不需要增强可以不配(建议配置一下)
knife4j:
  enable: true
  setting:
    language: zh_cn

        3. 在需要的地方添加上注解

拿最重要的两个注解来说:

  • @Tag(name = "xxx")  加在controller类前,用于将不同controller类分开,xxx换成你想定义为什么名字
  • @Operation(summary = "xxx")  加在controller中各个方法前,用于定义这个方法的名字

实际效果举例:

解决knife4j无法访问

输入{ip}:{port}/doc.html 但无法访问,显示如下:

或者:

idea中有输出,如下:

解决办法:

第一:检查配置,是否配置了如下内容:

spring:
  web:
    resources:
      add-mappings: false

如果有,那么把这个false改成true,或者删掉这个配置(没有配置的话默认是true)

第二:检查是否使用了响应(返回)结果封装器

响应结果封装器,即一个实现了Spring MVC中的HandlerMethodReturnValueHandler的方法,通常用于在方法返回值写入HTTP响应体之前进行预处理。

我定义了响应结果封装器,并通过自定义注解加在了模块的启动类上,这就导致了所有响应结果都会被这个封装器处理(好处是可以偷懒,不需要每个接口都封装返回结果)。

knife4j,将无法识别封装后的响应结果,导致knife4j请求文档异常。

解决办法很简单,就是放弃使用结果封装器(啊这……)

我不知道怎么让封装器对knife4j的结果特判,使返回结果不封装直接返回,因此只能弃用,如果有大佬知道怎么搞可以在评论说一下,提前感谢

以下是一些关于怎么找到这个解决办法(微服务项目debug)的经验(吐槽)分享

其实本文没什么内容,但我因为这个问题搞了两天,网上没有找到这个解决办法(至少我没找到……),因此特来发此文,希望别人遇到这个问题时能看到这个解决办法

因为本人以前搞的项目都是用的springboot2.x,最近弄到一个使用3.2.4的项目,因为用knife4j测试接口非常方便,没想到一搞搞了两天……

首先因为springboot2.x和3.x之间的巨大差异,原来的依赖以及使用方式都不在适用,本人搜索了几个小时后,才“阴差阳错”的发现了这一点……

当然解决这一点后仍然有其它问题,/doc.html仍然不能使用,然后我用git做好备份,然后疯狂删东西:

首先,我把微服务中其它模块全部删掉,只保留了一个模块,以方便排除模块间影响

第二,把模块中所有文件删除,只留了一个极其简单的controller类测试,测试后/doc.html仍然未能访问,因此排除了其它模块的影响(比如网关、过滤器、拦截器等)

第三,因为模块中除了一个controller类和一个启动类没别的东西了,因此怀疑是pom中的问题,开始删除pom中的依赖

重点:对pom中的依赖,使用二分删除法,删完后跑一遍,不行换着删。

几次操作后,发现当我删掉nacos相关的依赖后,/doc.html就变得可以访问了,因此确定是nacos中的配置引起问题。

对nacos中的配置:再次使用二分删除法,最终确定是关于springmvc的一个配置,删掉它就好了,因此再次确定具体的配置项(又是二分……)  终于发现了问题所在……

关于spring.web.resources.add-mappings 属性(以下为ai的回答)

spring.web.resources.add-mappings 属性用于控制是否应该添加默认的资源映射。资源映射是指将URL路径映射到静态资源位置,如HTML、CSS、JavaScript文件等。

默认情况下,Spring Boot会自动配置一些资源映射,以便你可以轻松地访问位于classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/等目录下的静态资源。

当你设置spring.web.resources.add-mappingsfalse时,Spring Boot将不会添加这些默认的资源映射。这在你想要完全自定义资源映射时很有用,例如,如果你想要改变静态资源的默认位置,或者你想要使用不同的URL路径来访问这些资源。

简而言之,这个配置用于禁用Spring Boot的默认静态资源映射功能。禁用后,你需要手动配置静态资源的映射,如果你没有提供任何映射,那么你的应用程序将无法直接访问这些静态资源。

(更新)

然而!问题并没有完全解决!

关于上面的配置,那个确实是要改的,但我改完之后回滚项目,发现还是不行

生无可恋我的又开始又开始排查,因为之前模块内只留了一个controller,太干净了,因此这次怀疑是模块内的问题。

这次的debug策略是逐步还原模块内容,每次成功做好版本备份,缩小搜索范围。

以下使用一个名叫TortoiseGit的工具,强烈推荐ㄟ(≧◇≦)ㄏ 

搜了下已经有教程了,我就不介绍了。有不懂的可以在评论区问

还原顺序:

        1. 还原实体类,配置类,工具类

        2. 还原mapper包

        3. 还原service包

        4.还原其它包,如listener包等

        5.还原controller包

关于怎么还原部分代码:选择之前备份的版本,在下面找到需要的代码,shift多选后右键,选“还原到此版本”

在将上面所有包还原且没有发现问题后,那么就只剩下启动类了

关于启动类,使用工具进行找bug会比较方便,我这里将原来的代码和现在的代码进行比对,找bug非常方便(左边的是原来版本,右边是现在版本,会动态更新)

右键需要比对的文件,点“与工作副本比较”

通过不断还原部分代码,发现问题在一个名叫EnableDefaultResponseAdvice的注解,按住ctrl点进去看,最终看到了项目中的全局默认封装器。

事已至此,情况就比较清晰了,尝试性的将 return RestResult.ok(body); 改为 return body; 后,问题解决。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐