问题描述
在学习黑马的苍穹外面项目的时候,由于jdk版本问题,修改了spring boot的版本为3.x,而后导致Swagger用不了了,如下图
网上找到的结果是:springboot3.x不支持Knife4j的3.0~3.0.3版本,因此需要换为最新版本。
Knife4j4.0配置
一、简介
官网:Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j
Knife4j是一个集Swagger2 和 OpenAPI3 为一体的增强解决方案
Knife4j 是为 Java MVC 框架集成 Swagger 生成 Api 文档的增强解决方案,前身是 swagger-bootstrap-ui
,致力于 springfox-swagger
的增强 UI 实现。knife4j 为了契合微服务的架构发展,由于原来 swagger-bootstrap-ui
采用的是后端 Java 代码 + 前端 UI 混合打包的方式,在微服务架构下显的很臃肿,因此项目正式更名为 knife4j,更名后主要专注的方面如下:
-
后端 Java 代码以及前端 UI 模块进行了分离,在微服务架构下使用更加灵活
-
提供专注于 Swagger 的增强解决方案,不同于只是单纯增强前端 UI 部分
二、版本说明
版本 | 说明 |
---|---|
1.0~1.9.6 | 名称是叫swagger-bootstrap-ui ,蓝色风格Ui |
1.9.6 | 蓝色皮肤风格,开始更名,增加更多后端模块 |
2.0~2.0.5 | Ui基于Vue2.0+AntdV重写,黑色风格,参考示例,底层依赖的springfox框架版本是2.9.2,仅提供Swagger2规范的适配 |
2.0.6~2.0.9 | 底层springfox框架版本升级知2.10.5,,仅提供Swagger2规范的适配 |
3.0~3.0.3 | 底层依赖springfox框架版本升级至3.0.3,OpenAPI规范是v3,过度版本,建议开发者不要使用 |
4.0~ | 区分OpenAPI2和Swagger3的Maven坐标artifactId OpenAPI2规范服务端解析框架稳定在springfox2.10.5 OpenAPI3框架服务端解析跟随springdoc项目更新迭代 建议开发者使用该版本,请参考4.x升级文档 |
Spring Boot版本兼容性
Spring Boot版本 | Knife4j Swagger2规范 | Knife4j OpenAPI3规范 |
---|---|---|
1.5.x~2.0.0 | <Knife4j 2.0.0 | >=Knife4j 4.0.0 |
2.0~2.2 | Knife4j 2.0.0 ~ 2.0.6 | >=Knife4j 4.0.0 |
2.2.x~2.4.0 | Knife4j 2.0.6 ~ 2.0.9 | >=Knife4j 4.0.0 |
2.4.0~2.7.x | >=Knife4j 4.0.0 | >=Knife4j 4.0.0 |
>= 3.0 | >=Knife4j 4.0.0 | >=Knife4j 4.0.0 |
nife4j版本 | Swagger2规范 | OpenAPI3规范 | 说明 |
---|---|---|---|
1.0~1.9.6 | springfox 2.9.2 | 无 | Knife4j的前身,名称为swagger-bootstrap-ui |
1.9.6~2.0.5 | springfox 2.9.2 | 无 | |
2.0.6~2.0.9 | springfox 2.10.5 | 无 | |
3.0.0~3.0.3 | springfox 3.0.3 | 无 | 过度版本,建议开发者不要使用 |
4.0.0~ | springfox 2.10.5 | >=springdoc-openapi 1.6.9 | Swagger2规范稳定使用springfox2.10.5保持不变。开发者应该尽早迁移到OpenAPI3规范上来,请参考4.x升级文档 |
三、使用
1.引入依赖
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId> <version>4.3.0</version> </dependency>
2.修改配置文件application.yml
# 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 # knife4j的增强配置,不需要增强可以不配 knife4j: enable: true setting: language: zh_cn
3.编写配置类
package com.sky.config; import io.swagger.v3.oas.models.OpenAPI; 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 lombok.extern.slf4j.Slf4j; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 通过knife4j生成接口文档 * @return */ @Configuration @Slf4j public class Knife4jConfiguration { /** * 管理端接口文档 * @return */ @Bean public GroupedOpenApi adminApi() { log.info("准备生成接口文档"); return GroupedOpenApi.builder() // 创建了一个api接口的分组 .group("管理端接口") // 分组名称 .pathsToMatch("/admin/**") // 接口请求路径规则 .build(); } /** * 用户端接口文档 * @return */ @Bean public GroupedOpenApi userApi() { log.info("准备生成接口文档"); return GroupedOpenApi.builder() // 创建了一个api接口的分组 .group("用户端接口") // 分组名称 .pathsToMatch("/user/**") // 接口请求路径规则 .build(); } @Bean public OpenAPI openAPI(){ return new OpenAPI() .info(new Info() .title("苍穹外卖项目接口文档") .description("苍穹外卖项目接口文档") .version("v1") .contact(new Contact().name("robin").email("robin@gmail.com")) .license(new License().name("Apache 2.0").url("http://springdoc.org")) ); } }
其中pathsToMatch用于匹配对应的接口,其匹配的是接口的url地址
然后在WebMVCConfiguration中设置静态资源映射
/** * 设置静态资源映射 * @param registry */ protected void addResourceHandlers(ResourceHandlerRegistry registry) { log.info("开始设置静态资源映射"); registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); }
4.编写User类用作模型
package com.mcode.knife4jdemo.entity; import io.swagger.v3.oas.annotations.media.Schema; /** * ClassName: User * Package: com.mcode.knife4jdemo.entity * Description: * * @Author: robin * @Version: v1.0 */ @Schema(description = "用户实体") public class User { @Schema(description = "用户名称") private String userName; @Schema(description = "密码") private String password; @Schema(description = "邮箱") private String email; @Schema(description = "年龄") private int age; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public User() { } public User(String userName, String password, String email, int age) { this.userName = userName; this.password = password; this.email = email; this.age = age; } }
5.编写控制器
package com.mcode.knife4jdemo.controller; import com.mcode.knife4jdemo.entity.User; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; /** * ClassName: IndexController * Package: com.mcode.knife4jdemo.controller * Description: * * @Author: robin * @Version: v1.0 */ @RestController @Tag(name = "首页") @RequestMapping("/admin/index") public class IndexController { @Operation(summary = "获取用户") @GetMapping("/getUser") public User getUser( @Parameter(name = "userName",description = "用户名称",in = ParameterIn.QUERY)String userName) { return new User(userName, "123456", "123@qq.com", 18); } @Operation(summary = "新增用户") @PostMapping("/addUser") public Boolean addUser(@RequestBody User user) { return true; } }
运行项目,访问:http://ip:port/doc.html
解决方法
配置完如上之后,发现仍然不行,还是报错。
然后忽然想起在三小时前看到的一篇文章:Knife4j文档请求异常(基于SpringBoot3,查找原因并解决)-CSDN博客
跟着他的思路,F12打开控制台准备进行debug,发现报出如下错误:
大致意思是JSON返回了一个token,继续从网络的响应查找:
发现响应码(200)正常,并且返回格式为json,查看响应内容:
相应内容是一长串字符串,而不是Json数据
最后发现是之前设置过一个消息转换器,将Date类型转换为yyyy-MM-dd HH:mm格式去显示,消息转换器将JSON数据不正常解析
于是将消息转换器注释掉,便正常显示了:
如果还想保留消息转换器,让后端返回正确的时间数据格式,那么可以调整消息转换器列表中转换器的顺序,代码如下:
/** * 扩展消息转换器,将日期类型从列表转换为时间戳 * 这个是导致knife4j不能正常显示的罪魁祸首,特别要注意添加的位置 * @param converters 消息转换器列表 */ @Override protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); jackson2HttpMessageConverter.setObjectMapper(new JacksonObjectMapper()); converters.add(converters.size()-1,jackson2HttpMessageConverter); }
参考文章
官方文档(快速开始):快速开始 | Knife4j
官方文档(详细介绍):3.1 增强模式 | Knife4j
Spring Boot3整合knife4j(swagger3)-阿里云开发者社区
https://www.cnblogs.com/vic-tory/p/17773531.html