這篇文章主要記錄升級(jí)到 fastjson2.x 版本后出現(xiàn)的一些問題?
1. jar 包引入問題
問題描述:從 2.x 版本后,fastjson 貌似開始對(duì)代碼模塊進(jìn)行了拆分,所以在調(diào)整配置的時(shí)候,會(huì)發(fā)現(xiàn)有些類突然沒了,其實(shí)是需要引入其他的擴(kuò)展包。
從 2.0.22 版本開始,需要引入下面三個(gè) jar 包
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension-spring5</artifactId>
</dependency>
起初的 2.x 版本,只需要引入前兩個(gè) jar 包,后面想更新一下新版本,好家伙,又分出來一個(gè)?fastjson2-extension-spring5,其實(shí)就是將 spring 的一些相關(guān)的配置類獨(dú)立出來了。
?用的最多應(yīng)該是 redis 的序列化類,還有 http 的消息解析器。
2. 自定義序列化?ObjectWriter 類的 writeXXX 方法問題
問題描述:1.x 版本中?SerializeWriter 的 write 方法,在 2.x 版本中?ObjectWriter 并沒有提供,反而提供很多不同的 writeXXX 方法,匹配不同的返回類型,如 writeString 方法,就會(huì)返回一個(gè)字符類型。
之前系統(tǒng)使用 1.2.83 版本,寫了一個(gè) LocalDateTime 序列化為時(shí)間戳毫秒數(shù)的自定義序列化類,使用的是?SerializeWriter 的 write 方法。
public class DateJsonSerializer implements ObjectSerializer {
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.getWriter();
if (object == null) {
serializer.getWriter().writeNull();
return;
}
if (object instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) object;
out.write(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() + "");
}
}
}
控制器測(cè)試代碼如下
@GetMapping("/test")
public DemoTestResponse test() {
DemoTestResponse response = new DemoTestResponse();
response.setDateTime(LocalDateTime.now());
return response;
}
返回對(duì)象如下
@Data
public class DemoTestResponse {
@JSONField(name = "date_time", serializeUsing = DateJsonSerializer.class)
private LocalDateTime dateTime;
}
postman 運(yùn)行后結(jié)果如下,可以看到自定義序列化生效了,并且返回了數(shù)字型的時(shí)間戳。
?升級(jí)到 2.x 版本后,重寫了這個(gè)自定義序列化類,如下
public class DateJsonSerializer implements ObjectWriter {
@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
if (object == null) {
jsonWriter.writeNull();
return;
}
if (object instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) object;
jsonWriter.writeString(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()+"");
}
}
}
這里使用了 JSONWriter 的 writeString 方法,這也是問題所在,還是運(yùn)行上面的方法,返回結(jié)果如下,變?yōu)榱艘粋€(gè)字符串了。
因?yàn)楫?dāng)時(shí)沒留意,所以就以為 writeString 的意思是參數(shù)為字符串類型就用了。其實(shí)?JSONWriter?類提供了很多的 writeXXX 方法。
?這里我們應(yīng)該使用 writeMillis 方法,如下圖
@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
if (object == null) {
jsonWriter.writeNull();
return;
}
if (object instanceof LocalDateTime) {
LocalDateTime localDateTime = (LocalDateTime) object;
jsonWriter.writeMillis(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
}
}
運(yùn)行結(jié)果如下,問題解決。?
3.?JSONField 注解智能匹配失效
問題描述:在使用 1.x 版本時(shí),字段使用的@JSONField(name = "openid"),前端傳過來的字段名為 open_id,接口能正常運(yùn)行。但是升級(jí)到 2.x 版本時(shí),就為空值。
這是一個(gè)隱藏很深的bug,估計(jì)是當(dāng)時(shí)開發(fā)接口的時(shí)候也沒有注意,接口已能夠正常運(yùn)行。但是升級(jí)到 2.x 版本時(shí),就出問題了。
其實(shí)這得益于 fastjson 的智能匹配,忽略了大小寫和下劃線,依然將 json 映射成功。但是在 2.x 版本后,貌似智能匹配并沒有默認(rèn)開啟,所以就出現(xiàn)映射不成功的情況。
筆者嘗試使用 開啟智能匹配,但是沒有成功,原因未明,先記錄下來,后面有時(shí)間去看一下源碼。從官網(wǎng)的 Issues 來看,也有不少這種序列化和反序列化的問題,先版本的更新也針對(duì)這種情況的比較多。
請(qǐng)求接收的 bean 如下,使用?JSONReader.Feature.SupportSmartMatch ,依舊是使用 openid 這個(gè)字段名稱。
@Data
public class XcUserEquityRequest {
@JSONField(name = "app_id")
private String appId;
@JSONField(name = "openid", deserializeFeatures= JSONReader.Feature.SupportSmartMatch)
private String openId;
}
請(qǐng)求的時(shí)候,依舊使用 open_id 下劃線的形式。
?但是接口映射的openid字段為空。
官方對(duì) SupportSmartMatch 的說明如下,文章來源:http://www.zghlxwxcb.cn/news/detail-642036.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-642036.html
到了這里,關(guān)于【fastjson2.x 記錄】那些從1.x升級(jí)到2.x踩過的坑的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!