在 springboot3.x 使用 knife4j 以及常见报错汇总

目录

引言: 

引入依赖: 

配置文件: 

过滤静态资源:

 增强模式:

便捷地址访问:

常见问题: 

注解使用实例: 


📄 ​文档参考地址​:
SpringBoot 3.x 结合 Swagger3 (Knife4j )踩坑实录 - 古渡蓝按 - 博客园 🔍

🏛️ ​官方文档地址​:
快速开始 | Knife4j📚

💡 ​背景来源​:
想在微服务项目使用 Knife4j,但是找了很多文档使用后访问地址无法显示 😵。经过实践和排查,终于解决了问题 ✅!

引言: 

首先,重点强调 Spring Boot 3.x 只支持 OpenAPI3 规范:

  • Knife4j提供的starter已经引用springdoc-openapi的jar,开发者需注意避免jar包冲突
  • JDK版本必须 >= 17
  • 详细Demo请参考knife4j-spring-boot3-demo

在 Spring Boot 3.x 项目中,如果你看到 swagger-annotations 依赖,通常意味着你正在使用 ​Springfox Swagger​(如 springfox-swagger2),而它 ​不兼容 Spring Boot 3.x​(因为 Spring Boot 3 迁移到了 Jakarta EE 9+,而 Springfox 仍依赖旧的 javax.servlet 包)。 

<!-- 删除这些 Springfox 依赖 -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.10.5</version>
</dependency>
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.10.5</version>
</dependency>

SpringDoc 是 Spring Boot 3.x 的官方推荐替代方案,完全兼容 Jakarta EE 9+: 

Springfox (旧)SpringDoc (新)作用
@Api@Tag类级别的 API 描述
@ApiOperation@Operation方法级别的 API 描述
@ApiParam@Parameter参数描述
@ApiModel@Schema模型描述

所以我们需要更换新的依赖,也就是Knife4j4.x,这样才能在 Spring Boot 3.x 项目中使用。

引入依赖: 

首先引入依赖:

<!--   添加swagger核心依赖-->
<dependency><groupId>io.swagger.core.v3</groupId><artifactId>swagger-core</artifactId><version>2.2.20</version>
</dependency>
<!--添加knife4j依赖-->
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.4.0</version>
</dependency>
<!--添加Springdoc依赖-->
<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-api</artifactId><version>2.2.0</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
<!--仅添加上述依赖,仍有可能报错,需补充以下依赖-->
<dependency><groupId>com.fasterxml.jackson.module</groupId><artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId><version>2.13.3</version>
</dependency>
<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.4.0-b180830.0359</version>
</dependency>

配置文件: 

我们一共要引入三个配置类和一个配置文件:

引入配置文件,这里因为我在开发微服务,所以在bootstrap.yml进行配置,如果正常开发Springboot项目的话,在application.yml配置即可:

尽需改写文档扫描包路径即可,配置成自己项目的controller包路径。 

server:servlet:context-path: /contentport: 63040# springdoc-openapi项目配置
springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: 'default'paths-to-match: '/**'# 生成文档所需的扫包路径,一般为启动类目录packages-to-scan: com.xuecheng.content.api
# knife4j的增强配置,不需要增强可以不配
knife4j:# 是否启用增强设置enable: true# 是否启用登录认证basic:enable: trueusername: adminpassword: 123456setting:language: zh_cnenable-version: trueenable-swagger-models: trueswagger-model-name: 用户模块

过滤静态资源:

Spring MVC配置类,主要用于处理网站图标(favicon.ico)的请求

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @Classname FaviconConfiguration* @Description 添加配置文件,处理favicon.ico请求* @Version 1.0.0* @Date 2025/5/26 13:39* @Created by Administrator*/
@SpringBootConfiguration
public class FaviconConfiguration implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new HandlerInterceptor() {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {if (!"GET".equalsIgnoreCase(request.getMethod()) || !request.getRequestURI().toString().equals("/favicon.ico")) {return true;}response.setStatus(HttpStatus.NO_CONTENT.value()); // 设置状态码为204 No Contentreturn false;}}).addPathPatterns("/**");}
}

 增强模式:

自定义生成的Swagger/OpenAPI文档的展示信息,提供一些项目信息或者个人的信息。

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.List;/*** Swagger2配置信息* 这里分了两组显示* 第一组是api,当作用户端接口* 第二组是admin,当作后台管理接口* 也可以根据实际情况来减少或者增加组** @author eleven_lxs* @date 2025-05-26 22:17*/
@Configuration
public class SwaggerConfig {@Beanpublic OpenAPI swaggerOpenAPI(){return new OpenAPI().info(new Info().title("标题")// 信息.contact(new Contact().name("作者").email("邮箱").url("地址"))// 简介.description("我的API文档")// 版本.version("v1")// 许可证.license(new License().name("Apache 2.0").url("http://springdoc.org"))).externalDocs(new ExternalDocumentation().description("外部文档").url("https://springshop.wiki.github.org/docs"));}
}

便捷地址访问:

 而为了方便直接通过点击地址直接访问,我们编写配置类帮助我们直接访问:

import io.micrometer.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Optional;/*** @Classname DocumentationConfig* @Description TODO* @Version 1.0.0* @Date 2025/5/26 15:28* @Created by Administrator*/
@Configuration
@Slf4j
public class DocumentationConfig implements ApplicationListener<ApplicationReadyEvent> {@Autowiredprivate Environment env;@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {String protocol = env.getProperty("server.ssl.key-store") != null ? "https" : "http";System.out.println(env);// 获取端口(添加默认值8080)String serverPort = env.getProperty("server.port", "8000");// 处理contextPath(避免null拼接)String contextPath = Optional.ofNullable(env.getProperty("server.servlet.context-path")).orElse("");String docPath = contextPath + "/doc.html";// 获取主机地址String hostAddress;try {hostAddress = InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {hostAddress = "localhost";log.warn("无法获取主机IP,使用默认地址: localhost");}log.info("""----------------------------------------------------------\t应用程序 "{}" 已启动\t文档访问地址:\t本地: \t{}://localhost:{}{}\t外部: \t{}://{}:{}{}\t激活配置: \t{}----------------------------------------------------------""",env.getProperty("spring.application.name", "默认应用"),protocol, serverPort, docPath,protocol, hostAddress, serverPort, docPath,Arrays.toString(env.getActiveProfiles()));}
}

常见问题: 

如果是开发微服务,这里可能会出现 http://localhost:63040/doc.html ,这里我的问题是出自在bootstrap.yml是Spring Cloud的配置文件,但在普通Spring Boot应用中不会自动加载,如果想使用,要添加spring-cloud-starter-bootstrap依赖才能生效:

<!-- 使bootstrap.yml生效 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>4.1.5</version> <!-- 与Spring Boot版本匹配 -->
</dependency>

随后在启动类下面可以添加代码进行测试:

@SpringBootApplication
public class ContentApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(ContentApplication.class, args);printEnvInfo(context);}private static void printEnvInfo(ConfigurableApplicationContext context) {Environment env = context.getEnvironment();System.out.println("\n=== 应用配置信息 ===");System.out.println("应用名称: " + env.getProperty("spring.application.name"));System.out.println("服务端口: " + env.getProperty("server.port"));System.out.println("上下文路径: " + env.getProperty("server.servlet.context-path"));System.out.println("激活Profile: " + Arrays.toString(env.getActiveProfiles()));System.out.println("数据库URL: " + env.getProperty("spring.datasource.url"));System.out.println("Swagger路径: " + env.getProperty("springdoc.swagger-ui.path"));}
}

 而我为了方便,我直接配置了一个新的application.yml,发现一样好使:

server:port: 63040

另外如果还是没有显示,那么去检查你的 SecurityConfig 配置,确保 SecurityConfig 放行所有文档路径:

@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth.requestMatchers("/content/swagger-ui/​**​","/content/v3/api-docs/​**​","/content/doc.html","/content/webjars/​**​").permitAll().anyRequest().authenticated());return http.build();}
}

注解使用实例: 

import com.xuecheng.base.model.PageParams;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.dto.QueryCourseParamsDto;
import com.xuecheng.content.model.po.CourseBase;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;@Tag(name = "课程信息管理接口", description = "课程信息管理接口")  // 替代 @Api
@RestController
public class CourseBaseInfoController {@Operation(summary = "课程查询接口")  // 替代 @ApiOperation@PostMapping("/course/list")public PageResult<CourseBase> list(@Parameter(description = "分页参数") PageParams pageParams,  // 替代 @ApiParam@Parameter(description = "查询条件") @RequestBody(required = false) QueryCourseParamsDto queryCourseParamsDto) {CourseBase courseBase = new CourseBase();courseBase.setName("测试名称");courseBase.setCreateDate(LocalDateTime.now());List<CourseBase> courseBases = new ArrayList<>();courseBases.add(courseBase);return new PageResult<>(courseBases, 10, 1, 10);}
}
import lombok.Data;
import lombok.ToString;
import io.swagger.v3.oas.annotations.media.Schema;@Data
@ToString
@Schema(name = "PageParams", description = "分页查询参数") // 类级别描述(可选)
public class PageParams {@Schema(description = "页码", example = "1", defaultValue = "1")private Long pageNo = 1L;@Schema(description = "每页记录数", example = "30", defaultValue = "30")private Long pageSize = 30L;public PageParams() {}public PageParams(Long pageNo, Long pageSize) {this.pageNo = pageNo;this.pageSize = pageSize;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907183.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C/C++】环形缓冲区:高效数据流转核心

文章目录 1 核心结构与原理1.1 组成1.2 内存布局1.3 关键操作 2 实现细节与优化2.1 满/空状态的判断2.2 多线程安全&#xff08;无锁实现&#xff09;2.3 性能优化 3 典型应用场景4 代码示例5 优缺点6 对比7 进阶 环形缓冲区&#xff08;Ring Buffer&#xff09;&#xff0c;又…

功耗仅4W!迷你服务器黑豹X2(Panther X2)卡刷、线刷刷入Armbian(ubuntu)系统教程

功耗仅4W&#xff01;迷你服务器黑豹X2&#xff08;Panther X2&#xff09;卡刷、线刷刷入Armbian&#xff08;ubuntu&#xff09;系统教程 前言 前段时间逛海鲜市场的时候留意到一个矿渣盒子&#xff0c;黑豹x2&#xff0c;又是一个类似迅雷赚钱宝这样的挖矿项目已经gg的定制…

【Elasticsearch】更新操作原理

Elasticsearch 的更新操作&#xff08;如 _update 和 _update_by_query&#xff09;在底层实现上有一些复杂的原理&#xff0c;这些原理涉及到 Elasticsearch 的数据存储机制、索引机制以及事务日志&#xff08;Translog&#xff09;的使用。以下是 Elasticsearch 更新操作的主…

【C++】红黑树的实现

目录 前言 一、红黑树的概念 二、红黑树的实现 三、红黑树的查找 四、红黑树的验证 五、红黑树的删除 总结 前言 本文讲解红黑树&#xff0c;主要讲解插入部分的实现&#xff0c;建议在理解了AVL树的旋转后再来学习红黑树&#xff0c;因为红黑树也涉及旋转&#xff0c;并…

IPv4地址的主要配置项介绍

1. IPv4 主要配置项 (1) IP 地址&#xff08;IP Address&#xff09; 作用&#xff1a;唯一标识网络中的设备&#xff08;如 192.168.1.100&#xff09;。分类&#xff1a; 静态 IP&#xff1a;手动配置&#xff0c;适用于服务器、打印机等固定设备。动态 IP&#xff08;DHCP…

nginx 基于IP和用户的访问

nginx的下载 yum install nginx.x86_64 -y 启动服务 systemctl enable --now nginx.service 查看服务目录 [rootwebserver ~]# rpm -ql nginx /usr/bin/nginx-upgrade /usr/lib/systemd/system/nginx.service /usr/share/man/man3/nginx.3pm.gz /usr/share/man/man8/nginx…

Debian操作系统全面解析:从起源到应用

Debian 操作系统全面解析:从起源到应用 在开源操作系统的广袤天地中,Debian 占据着极为重要的地位。它凭借自身诸多突出特性,吸引了全球无数用户与开发者的目光,从个人桌面应用到大型服务器部署,从普通办公场景到专业科研领域,Debian 都展现出了强大的适应性与可靠性,为…

【springMVC】springMVC学习系列一:springMVC的组件

系列文章目录 前言 spring mvc 它解决了什么问题呢&#xff1f; 1.URL映射 2. 表单参数映射 3. 调用目标Control 4. 数据模型映射 5. 视图解析 6. 异常处理 上述解决在spring mvc 中都体现在如下组件当中 HandlerMapping&#xff1a; url与控制器的映谢 HandlerAdapter&#…

【Vue Vapor Mode :技术突破与性能优化的可能性】

Vue Vapor Mode &#xff1a;技术突破与性能优化的可能性 前言 作为一名有着Vue 2经验和Vue 3经验的开发者&#xff0c;你一定深刻体会过Vue从Options API到Composition API的演进&#xff0c;也感受过Vue 3在性能上相比Vue 2的显著提升。现在&#xff0c;Vue团队正在开发一个…

MySQL数据库零基础入门教程:从安装配置到数据查询全掌握【MySQL系列】

第1章&#xff1a;认识MySQL 1.1 什么是MySQL&#xff1f; MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;现由Oracle公司维护。它使用结构化查询语言&#xff08;SQL&#xff09;进行数据库的管理和操…

AXI3、AXI4 和 AXI5 的详细差异对比

AXI3、AXI4 和 AXI5 的详细差异对比 摘要&#xff1a;AXI (Advanced eXtensible Interface) 是 ARM 公司提出的高性能片上总线协议&#xff0c;广泛用于 SoC (System on Chip) 设计中&#xff0c;以实现高效的数据传输和系统互连。AXI 协议随着版本的迭代不断演进&#xff0c;从…

向量数据库该如何选择?Milvus 、ES、OpenSearch 快速对比:向量搜索能力与智能检索引擎的应用前景

​ 1.milvus VS ES Milvus 的亮点 功能性&#xff1a;Milvus 不仅支持基本的向量相似性搜索&#xff0c;还支持稀疏向量、批量向量、过滤搜索和混合搜索功能等高级功能。 灵活性&#xff1a;Milvus 支持多种部署模式和多个 SDK&#xff0c;所有这些都在一个强大的集成生态系…

SQL进阶之旅 Day 4:子查询与临时表优化

文章标题 【SQL进阶之旅 Day 4】子查询与临时表优化 文章内容 开篇&#xff1a;SQL进阶之旅的第4天 在“SQL进阶之旅”系列中&#xff0c;第4天的主题是子查询与临时表优化。这是SQL开发中不可或缺的一部分&#xff0c;尤其在处理复杂查询时&#xff0c;合理使用子查询和临…

Python学习(2) ----- Python的类型

在 Python 中&#xff0c;一切皆对象&#xff0c;每个对象都有类型。下面是 Python 中的常见内置类型分类和示例&#xff1a; &#x1f7e1; 1. 数字类型&#xff08;Numeric Types&#xff09; 类型说明示例int整数5, -42float浮点数3.14, -0.5complex复数1 2j a 10 …

跨协议协同智造新实践:DeviceNet-EtherCAT网关驱动汽车焊接装配效能跃迁

在汽车制造领域&#xff0c;机器人协作对于提升生产效率与产品质量至关重要。焊接、装配等关键环节&#xff0c;需要机器人与各类设备紧密配合。JH-DVN-ECT疆鸿智能的devicenet从站转ethercat主站协议网关&#xff0c;成为实现这一高效协作的得力助手&#xff0c;尤其是在连接欧…

nginx之proxy_buffering的作用

Nginx 的缓冲机制是为了让后端能更快释放资源&#xff0c;而不是卡在慢客户端上&#xff0c;从而提升整体性能和并发能力。 现实中客户端和后端服务器之间的传输速率可能差异很大。Nginx 的缓冲机制正是为了解决这个不匹配问题。 假设没有缓冲&#xff08;即 proxy_buffering…

数据库相关问题

1.保留字 1.1错误案例&#xff08;2025/5/27&#xff09; 报错&#xff1a; java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near condition, sell…

GO 语言进阶之 进程 OS与 编码,数据格式转换

更多个人笔记见&#xff1a; github个人笔记仓库 gitee 个人笔记仓库 个人学习&#xff0c;学习过程中还会不断补充&#xff5e; &#xff08;后续会更新在github上&#xff09; 文章目录 进程信息OS操作基本例子 编码相关HASH 哈希Base64 encoding 基础64编码 数据格式转换和处…

如何用Spring Cache实现对Redis的抽象

我们在进行Java项目开发时候&#xff0c;经常会用到Redis缓存例如数据库里的一些信息、手机验证码之类的&#xff0c;正常写法就会像去连mysql一样&#xff0c;这种硬编码的方式肯定是非常不合适的。 Autowireprivate UserMapper userMapper;Autowireprivate StringCommand str…

CMake指令:file()

目录 1.简介 2.常用子命令&#xff08;COMMAND&#xff09; 2.1.COPY - 复制文件或目录 2.2.RENAME - 重命名文件或目录 2.3.REMOVE - 删除文件或目录 2.4.MAKE_DIRECTORY - 创建目录 2.5.READ - 读取文件内容 2.6.WRITE - 写入文件内容 2.7.GLOB - 按模式匹配文件 2…