fastjson轉(zhuǎn)換對(duì)象實(shí)體@JsonProperty不生效問(wèn)題及解決
fastjson轉(zhuǎn)換對(duì)象實(shí)體@JsonProperty不生效
項(xiàng)目場(chǎng)景
請(qǐng)求第三方應(yīng)用 返回json數(shù)據(jù)
問(wèn)題描述
第三方返回的數(shù)據(jù)中,存在java關(guān)鍵詞,無(wú)法直接使用原屬性名進(jìn)行對(duì)應(yīng) 例如(class、interface等)使用@JsonProperty注解不能返回正確的結(jié)果
@Data static class User{ ? ? ?@JsonProperty( "class") ? ? ?private String userClass; ? ? ?@JsonProperty("interface") ? ? ?private String userInterface; } public static void main(String[] args) { ? ? Map<String,Object> map = new HashMap<>(); ? ? map.put("class","測(cè)試"); ? ? map.put("interface","測(cè)試1"); ? ? String mapStr = JSONObject.toJSONString(map); ? ? System.out.println(mapStr); ? ? User user = JSONObject.parseObject(mapStr, User.class); ? ? System.out.println(user); }
正常情況來(lái)講 @JsonProperty 注解完全夠用,可以成功解析出想要的結(jié)果。
但往往事情并不是那么簡(jiǎn)單
執(zhí)行結(jié)果 :
{"interface":"測(cè)試1","class":"測(cè)試"}
User(userClass=null, userInterface=null)
可以看出并沒(méi)有成功映射到想要的數(shù)據(jù)
原因分析
具體原因感興趣的同學(xué)可以看下 JSONObject.parseObject 的源碼
解決方案
解決方法有兩種
1、修改屬性名稱,使用原屬性名 + “_”
@Data static class User{ ? ? @JsonProperty( "class") ? ? private String class_; ? ?@JsonProperty("interface") ? ?private String interface_; } public static void main(String[] args) { ? ? Map<String,Object> map = new HashMap<>(); ? ? map.put("class","測(cè)試"); ? ? map.put("interface","測(cè)試1"); ? ? String mapStr = JSONObject.toJSONString(map); ? ? System.out.println(mapStr); ? ? User user = JSONObject.parseObject(mapStr, User.class); ? ? System.out.println(user); }
執(zhí)行結(jié)果 :
{"interface":"測(cè)試1","class":"測(cè)試"}
User(class_=測(cè)試, interface_=測(cè)試1)
2、使用fastjson @JSONField注解
@Data static class User{ @JSONField(name = "class") private String userClass; @JSONField(name = "interface") private String userInterface; } public static void main(String[] args) { ? ? Map<String,Object> map = new HashMap<>(); ? ? map.put("class","測(cè)試"); ? ? map.put("interface","測(cè)試1"); ? ? String mapStr = JSONObject.toJSONString(map); ? ? System.out.println(mapStr); ? ? User user = JSONObject.parseObject(mapStr, User.class); ? ? System.out.println(user); }
執(zhí)行結(jié)果:
{"interface":"測(cè)試1","class":"測(cè)試"}
User(userClass=測(cè)試, userInterface=測(cè)試1)
@JsonProperty 失效問(wèn)題的排查
@JsonProperty 是Jackson提供的一個(gè)用于注解屬性、類、方法等的json注解。使用它可以改變Json序列化時(shí)屬性的名稱,一般默認(rèn)使用屬性名,比如如下的代碼示例,如果沒(méi)有使用@JsonProperty注解那么id轉(zhuǎn)化為json為{“id”:11}.使用了則就是{“Id”:11}.
@JsonInclude(Include.NON_NULL) public class User implements Serializable { @JsonProperty("Id") private Integer id; @JsonProperty("Name") private String name; @JsonProperty("pwd") private Integer passWord; }
在一次使用springboot項(xiàng)目時(shí)發(fā)現(xiàn)@JsonProperty不生效。
那么是因?yàn)樯赌兀?/strong>
因?yàn)樵陧?xiàng)目里還引用了fastJson,在debug時(shí)發(fā)現(xiàn)接口最后響應(yīng)時(shí)是使用FastJson做json序列化。
解決方法:
使用@EnableWebMvc注解,加在啟動(dòng)類上?;蛘咧苯釉陧?xiàng)目里不引用fastJson.
@EnableWebMvc public class SpringBootMain extends SpringBootServletInitializer implements WebApplicationInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SpringBootMain.class); } }
springboot 是如何選擇使用json序列化工具的呢?即如何調(diào)用jackson進(jìn)行json序列化和反序列化?
springboot 通過(guò)HttpMessageConverters 消息轉(zhuǎn)換器通過(guò)jackson將java對(duì)象轉(zhuǎn)化為json字符串。如果項(xiàng)目里包含多個(gè)json工具包比如jackson ,fastjson,那么就會(huì)各個(gè)年級(jí)對(duì)象的內(nèi)容選擇一個(gè)合適的去轉(zhuǎn)換為json。
這是HttpMessageConverters 消息轉(zhuǎn)換器所處的位置,所以項(xiàng)目里采用那個(gè)json工具由該類決定。
springboot默認(rèn)使用jackson,springboot默認(rèn)集成的就是jackson。
指定使用fastJson的一種做法:
public class SpringBootMain extends SpringBootServletInitializer implements WebApplicationInitializer { @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { // 1.定義一個(gè)converters轉(zhuǎn)換消息的對(duì)象 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); // 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json數(shù)據(jù) FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); // 3.在converter中添加配置信息 fastConverter.setFastJsonConfig(fastJsonConfig); // 4.將converter賦值給HttpMessageConverter HttpMessageConverter<?> converter = fastConverter; // 5.返回HttpMessageConverters對(duì)象 return new HttpMessageConverters(converter); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?Boot讀取配置文件內(nèi)容的3種方式(@Value、Environment和@ConfigurationP
工作中經(jīng)常會(huì)有一些參數(shù)需要配置,同時(shí)在代碼里面需要用到,所有就需要配置類讀取,然后在使用的時(shí)候注入該類進(jìn)行獲取相關(guān)參數(shù),下面這篇文章主要給大家介紹了關(guān)于Spring?Boot讀取配置文件內(nèi)容的3種方式,需要的朋友可以參考下2023-01-01Mybatis聯(lián)合查詢的實(shí)現(xiàn)方法
本文主要介紹了 Mybatis聯(lián)合查詢的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01springboot打成jar后獲取classpath下文件失敗的解決方案
這篇文章主要介紹了使用springboot打成jar后獲取classpath下文件失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java創(chuàng)建類模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java創(chuàng)建類模式的相關(guān)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08JAVA正則表達(dá)式及字符串的替換與分解相關(guān)知識(shí)總結(jié)
今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí)總結(jié),文章圍繞著JAVA正則表達(dá)式及字符串的替換與分解展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06JAVA初級(jí)項(xiàng)目——實(shí)現(xiàn)圖書管理系統(tǒng)
這篇文章主要介紹了JAVA如何實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06spring-boot中的SPI機(jī)制實(shí)例講解
這篇文章主要介紹了spring-boot中的SPI機(jī)制實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java RMI詳細(xì)介紹及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Java RMI詳細(xì)介紹及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02