如何在springboot3.x使用knife4j,以及knife4j无法访问(404)解决办法,微服务项目debug经验分享
微服务项目debug经验分享。knife4j(swagger)无法访问,状态码404。No mapping for GET /doc.html。No endpoint GET /doc.html.。解决办法是spring.web.resources.add-mappings属性配置为true,检查是否使用了响应(返回)结果封装器,封装结果后将无法使用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-mappings
为false
时,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; 后,问题解决。
更多推荐
所有评论(0)