knife4j 4.1.0版本文档请求异常
写在前面
一直以来使用的接口文档方案都是Knife4j。此次编写新项目,鉴于springfox和Swagger2规范都已经停止维护,所以选择拥抱springdoc+OpenAPI3规范。knife4j也已更新版本,本项目基于Spring Boot2.7.x版本。
忠告:一定要认真看官方文档
问题描述
项目中定义了实体类属性的时间格式为LocalDateTime,如果不做任何处理后端会向前端返回数组格式,而不是我们想要的时间格式。
1 | // 创建时间 |
像这种情况,以前的项目也遇到过,所以是轻松解决。这里说一下两种解决方案,推荐使用的是第二种。
第一种:
遇到这个问题是因为后端向前端发送的时间是一个LocalDateTime对象,我们只需要把该对象转成时间戳在发送即可。
在定义LocalDateTime类型的属性上上加上注解,对日期进行格式化
1 | // 创建时间 |
但这种方式,需要在每个时间属性都加上该注解,使用麻烦,耦合度高
第二种:
通过重写WebMvcConfigurationSupport里的消息转换器方法实现(全局),统一对日期类型进行格式处理
具体实现步骤:
- 提供对象转换器JacksonObjectMapper,基于Jackson进行Java对象到json数据的转换
- 在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
// 收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
// 反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
// 注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
WebMvcConfig配置类里重写消息转换器
在我重写消息转换器后导致了knife4j文档请求异常的出现,起初我并未发现该问题,因为在使用Postman进行接口测试,并没有打开文档。当我发现该问题,对比代码版本的变动后,我意识到可能是消息转换器导致了该问题的出现。
可以明显看到请求/v3/apis-docs路径返回的是Base64编码,就是因为没有正确返回json数据导致文档显示失败
解决方案
由于之前的项目也是使用的knife4j(Swagger2),也重写过消息转换器,并未出现该问题。当我一筹莫展,反复修改的情况下,突然想起我用的knife4j是新版的。于是乎,我打开了knife4j的官网……
没错,就是这样的,打开官网看一眼FAQ就可以解决了
ps:不要学我,用新版都不先看一眼文档(其实看了,就看了新版依赖坐标)
在查看GitHub的issues后,成功解决该问题。就是需要在拓展的自定义消息转换器前注册ByteArrayHttpMessageConverter,一定要注意顺序,不然还是会请求异常