Java中對象?和?json?互轉四種方式?json-lib、Gson、FastJson、Jackson
一、 json-lib
json-lib最開始的也是應用最廣泛的json解析工具,json-lib 不好的地方確實是依賴于很多第三方包,
包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
對于復雜類型的轉換,json-lib對于json轉換成bean還有缺陷,比如一個類里面會出現(xiàn)另一個類的list或者map集合,json-lib從json到bean的轉換就會出現(xiàn)問題。
json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求。
二、 Google的Gson
1.簡介
(1)Gson是目前功能最全的Json解析神器,Gson當初是為因應Google公司內(nèi)部需求而由Google自行研發(fā)而來 但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應用。
Gson的應用主要為toJson與fromJson兩個轉換函數(shù),無依賴,不需要例外額外的jar,能夠直接跑在JDK上。
而在使用這種對象轉換之前需先創(chuàng)建好對象的類型以及其成員才能成功的將JSON字符串成功轉換成相對應的對象。
類里面只要有get和set方法,Gson完全可以將復雜類型的json到bean或bean到json的轉換,是JSON解析的神器。
Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距。
(2)默認是不序列化null值對應的key的,具體案例如下:
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException { AutoPartsSearchRequest request = new AutoPartsSearchRequest(); request.setKeywords("123"); request.setSortingField("234242"); Gson g = new GsonBuilder().create(); String str = g.toJson(request); System.out.println(str); //輸出結果:{"sortingField":"234242","keywords":"123"} }
若是想序列化null值對應的key,只需要將以上創(chuàng)建代碼改成以下代碼就行:
Gson g = new GsonBuilder().serializeNulls().create();
若是想轉行null為空字符串"",則需要手動處理了
(3)主要類介紹
Gson類:解析json的最基礎的工具類
JsonParser類:解析器來解析JSON到JsonElements的解析樹
JsonElement類:一個類代表的JSON元素
JsonObject類:JSON對象類型
JsonArray類:JsonObject數(shù)組
TypeToken類:用于創(chuàng)建type,比如泛型List<?>
(4)bean轉換json
Gson gson = new Gson(); String json = gson.toJson(obj); //obj是對象
(5) json轉換bean
Gson gson = new Gson(); String json = "{\"id\":\"2\",\"name\":\"Json技術\"}"; Book book = gson.fromJson(json, Book.class);
(6) json轉換復雜的bean,比如List,Set
將json轉換成復雜類型的bean,需要使用TypeToken
Gson gson = new Gson(); String json = "[{\"id\":\"1\",\"name\":\"Json技術\"},{\"id\":\"2\",\"name\":\"java技術\"}]"; //將json轉換成List List list = gson.fromJson(json,new TypeToken<LIST>() {}.getType()); //將json轉換成Set Set set = gson.fromJson(json,new TypeToken<SET>() {}.getType());
(7) 通過json對象直接操作json以及一些json的工具
a) 格式化Json
String json = "[{\"id\":\"1\",\"name\":\"Json技術\"},{\"id\":\"2\",\"name\":\"java技術\"}]"; Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonParser jp = new JsonParser(); JsonElement je = jp.parse(json); json = gson.toJson(je);
b) 判斷字符串是否是json,通過捕捉的異常來判斷是否是json
String json = "[{\"id\":\"1\",\"name\":\"Json技術\"},{\"id\":\"2\",\"name\":\"java技術\"}]"; boolean jsonFlag; try { new JsonParser().parse(str).getAsJsonObject(); jsonFlag = true; } catch (Exception e) { jsonFlag = false; }
c) 從json串中獲取屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; String propertyName = 'id'; String propertyValue = ""; try { JsonParser jsonParser = new JsonParser(); JsonElement element = jsonParser.parse(json); JsonObject jsonObj = element.getAsJsonObject(); propertyValue = jsonObj.get(propertyName).toString(); } catch (Exception e) { propertyValue = null; }
d) 除去json中的某個屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; String propertyName = 'id'; JsonParser jsonParser = new JsonParser(); JsonElement element = jsonParser.parse(json); JsonObject jsonObj = element.getAsJsonObject(); jsonObj.remove(propertyName); json = jsonObj.toString();
e) 向json中添加屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; String propertyName = 'desc'; Object propertyValue = "json各種技術的調研"; JsonParser jsonParser = new JsonParser(); JsonElement element = jsonParser.parse(json); JsonObject jsonObj = element.getAsJsonObject(); jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue)); json = jsonObj.toString();
f) 修改json中的屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; String propertyName = 'name'; Object propertyValue = "json各種技術的調研"; JsonParser jsonParser = new JsonParser(); JsonElement element = jsonParser.parse(json); JsonObject jsonObj = element.getAsJsonObject(); jsonObj.remove(propertyName); jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue)); json = jsonObj.toString();
g) 判斷json中是否有屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; String propertyName = 'name'; boolean isContains = false ; JsonParser jsonParser = new JsonParser(); JsonElement element = jsonParser.parse(json); JsonObject jsonObj = element.getAsJsonObject(); isContains = jsonObj.has(propertyName);
h) json中日期格式的處理
GsonBuilder builder = new GsonBuilder(); builder.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); Gson gson = builder.create();
然后使用gson對象進行json的處理,如果出現(xiàn)日期Date類的對象,就會按照設置的格式進行處理
i) json中對于Html的轉義
Gson gson = new Gson();
這種對象默認對Html進行轉義,如果不想轉義使用下面的方法
GsonBuilder builder = new GsonBuilder(); builder.disableHtmlEscaping(); Gson gson = builder.create();
2. 配置步驟
1. MAVEN 依賴引入
<!--gson--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version> </dependency>
2. gsonUtil 工具類
package com.dechnic.common.util; import com.dechnic.common.anno.gson.Exclude; import com.dechnic.common.po.ObjectTypeAdapter; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.internal.LinkedTreeMap; import com.google.gson.reflect.TypeToken; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @description: * @author:houqd * @time: 2022/6/27 17:31 */ public class GsonUtll { private static Gson gson; static { ExclusionStrategy strategy = new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(Exclude.class) !=null; } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }; gson = new GsonBuilder().disableHtmlEscaping().setExclusionStrategies(strategy).registerTypeAdapter(new TypeToken<Map<String,Object>>(){}.getType(),new ObjectTypeAdapter()).serializeNulls().create(); } public static Map<String,Object> jsonStr2Map(String jsonStr){ return gson.fromJson(jsonStr, new TypeToken<Map<String, Object>>() { }.getType()); } public static List<Map<String,Object>> jsonStr2ListMap(String jsonStr){ return gson.fromJson(jsonStr, new TypeToken<List<Map<String, Object>>>() { }.getType()); } public static String toJSON(Object object){ return gson.toJson(object); } public static <T> List<T> json2ListBean(String result, Class<T> t){ List list = gson.fromJson(result, new TypeToken<List>() { }.getType()); List list2 = new ArrayList(); for (Object o : list) { list2.add(json2Bean(toJSON(o),t)); } return list2; } public static <T> T json2Bean(String result,Class<T>t){ return gson.fromJson(result, t); } }
3. 排除不要序列化的熟悉注解類 Exclude
package com.dechnic.common.anno.gson; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Exclude { }
三. 阿里巴巴的FastJson
1.簡介
(1)Fastjson是一個Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)。
無依賴,不需要例外額外的jar,能夠直接跑在JDK上。
FastJson在復雜類型的Bean轉換Json上會出現(xiàn)一些問題,可能會出現(xiàn)引用的類型,導致Json轉換出錯,需要制定引用。
FastJson采用獨創(chuàng)的算法,將parse的速度提升到極致,超過所有json庫。
(2)fastJson在轉換java對象為json的時候,默認是不序列化null值對應的key的,也就是說當對象里面的屬性為空的時候,在轉換成json時,不序列化那些為null值的屬性
但是如果想把null對應的key序列化出來呢?
那就要仔細看看fastjson轉換java對象為json的時候的入?yún)⒘耍阂簿褪沁@個方法:
JSONObject.toJSONString(Object object, SerializerFeature… features)
Fastjson的SerializerFeature序列化屬性:
QuoteFieldNames———-輸出key時是否使用雙引號,默認為true WriteMapNullValue——–是否輸出值為null的字段,默認為false WriteNullNumberAsZero—-數(shù)值字段如果為null,輸出為0,而非null WriteNullListAsEmpty—–List字段如果為null,輸出為[],而非null WriteNullStringAsEmpty—字符類型字段如果為null,輸出為”“,而非null WriteNullBooleanAsFalse–Boolean字段如果為null,輸出為false,而非null
結合上面,SerializerFeature… features是個數(shù)組,那么我們可以傳入我們想要的參數(shù),比如想序列化null,案例如下:
public static void main(String[] args) { AutoPartsSearchRequest request = new AutoPartsSearchRequest(); request.setKeywords("123"); request.setSortingField("234242"); String str = JSONObject.toJSONString(request, SerializerFeature.WriteMapNullValue); System.out.println(str); }
(3) bean轉換json將對象轉換成格式化的json
JSON.toJSONString(obj,true);
(4)將對象轉換成非格式化的json
JSON.toJSONString(obj,false);
obj設計對象
對于復雜類型的轉換,對于重復的引用在轉成json串后在json串中出現(xiàn)引用的字符,比如 ref":"[0].books[1]
Student stu = new Student(); Set books= new HashSet(); Book book = new Book(); books.add(book); stu.setBooks(books); List list = new ArrayList(); for(int i=0;i<5;i++) list.add(stu); String json = JSON.toJSONString(list,true);
(5) json轉換bean
String json = "{\"id\":\"2\",\"name\":\"Json技術\"}"; Book book = JSON.parseObject(json, Book.class);
(6) json轉換復雜的bean,比如List,Map
String json = "[{\"id\":\"1\",\"name\":\"Json技術\"},{\"id\":\"2\",\"name\":\"java技術\"}]"; //將json轉換成List List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){}); //將json轉換成Set Set set = JSON.parseObject(json,new TypeReference<HASHSET>(){});
(7)通過json對象直接操作json
a) 從json串中獲取屬性
String propertyName = 'id'; String propertyValue = ""; String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; JSONObject obj = JSON.parseObject(json); propertyValue = obj.get(propertyName));
b) 除去json中的某個屬性
String propertyName = 'id'; String propertyValue = ""; String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; JSONObject obj = JSON.parseObject(json); Set set = obj.keySet(); propertyValue = set.remove(propertyName); json = obj.toString();
c) 向json中添加屬性
String propertyName = 'desc'; Object propertyValue = "json的玩意兒"; String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; JSONObject obj = JSON.parseObject(json); obj.put(propertyName, JSON.toJSONString(propertyValue)); json = obj.toString();
d) 修改json中的屬性
String propertyName = 'name'; Object propertyValue = "json的玩意兒"; String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; JSONObject obj = JSON.parseObject(json); Set set = obj.keySet(); if(set.contains(propertyName)) obj.put(propertyName, JSON.toJSONString(propertyValue)); json = obj.toString();
e) 判斷json中是否有屬性
String propertyName = 'name'; boolean isContain = false; String json = "{\"id\":\"1\",\"name\":\"Json技術\"}"; JSONObject obj = JSON.parseObject(json); Set set = obj.keySet(); isContain = set.contains(propertyName);
f) json中日期格式的處理
Object obj = new Date(); String json = JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss.SSS");
簡單的使用場景:
2.配置步驟
1.引入maven
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency>
2. 配置 CustomFastjsonConfig
package com.example.demo2.config;/** * @className: WebMvcConfig * @author: houqd * @date: 2022/11/4 **/ import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; /** * @description: * @author:houqd * @time: 2022/11/4 13:55 */ @Configuration public class CustomFastjsonConfig { @Bean public FastJsonHttpMessageConverter fastjsonHttpMessageConverters() { FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setCharset(Charset.forName("UTF-8")); fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); //設置序列化特征 SerializerFeature[] serializerFeatures = new SerializerFeature[]{ //WriteNullStringAsEmpty: 如果字符串等于 null,那么會被序列化成空字符串 "" SerializerFeature.WriteNonStringKeyAsString, // WriteNullNumberAsZero: 如果數(shù)字等于 null,那么會被序列化成 0 SerializerFeature.WriteNullNumberAsZero, // WriteNullBooleanAsFalse: 如果布爾類型等于 null,那么會被序列化成 false SerializerFeature.WriteNullBooleanAsFalse, // PrettyFormat: 美化JSON SerializerFeature.PrettyFormat }; fastJsonConfig.setSerializerFeatures(serializerFeatures); // 配置添加到消息轉換器里面 converter.setFastJsonConfig(fastJsonConfig); converter.setDefaultCharset(Charset.forName("UTF-8")); // 設置響應JSON格式數(shù)據(jù) List<MediaType> mediaTypeList = new ArrayList<>(); mediaTypeList.add(MediaType.APPLICATION_JSON); // 設置消息轉換器支持的格式 converter.setSupportedMediaTypes(mediaTypeList); return converter; } }
3. 測試
User.java
package com.example.demo2.entity;/** * @className: User * @author: houqd * @date: 2022/11/4 **/ import lombok.Data; import java.io.Serializable; import java.util.Date; /** *@description: *@author:houqd *@time: 2022/11/4 14:12 * */ @Data public class User implements Serializable { private String username; private Date createTime; private Boolean enabled; private Integer num; } package com.example.demo2.entity;/** * @className: User * @author: houqd * @date: 2022/11/4 **/ import lombok.Data; import java.io.Serializable; import java.util.Date; /** *@description: *@author:houqd *@time: 2022/11/4 14:12 * */ @Data public class User implements Serializable { private String username; private Date createTime; private Boolean enabled; private Integer num; }
TestController.java
package com.example.demo2.controller;/** * @className: TestController * @author: houqd * @date: 2022/11/4 **/ import com.example.demo2.entity.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.Date; import java.util.List; /** *@description: *@author:houqd *@time: 2022/11/4 14:13 * */ @RestController @RequestMapping("/api") public class TestController { @GetMapping("/json") public List<User> json() { List<User> list = this.getUserList(); return list; } // 模擬數(shù)據(jù) private List<User> getUserList() { List<User> list = new ArrayList<>(); for (int i = 0; i < 3; i++) { User user = new User(); if (i != 1) { user.setUsername("test-00" + i); user.setCreateTime(new Date()); user.setEnabled(true); user.setNum(520); } list.add(user); } return list; } }
測試結果:
注意: fastJson 引用2.0.17 版本后 日期格式話失敗,退回到1.2.83 版本后正常。
4. 開源的Jackson 簡介:
(1)相比json-lib框架,Jackson所依賴的jar包較少,簡單易用并且性能也要相對高些。
而且Jackson社區(qū)相對比較活躍,更新速度也比較快。
Jackson對于復雜類型的json轉換bean會出現(xiàn)問題,一些集合Map,List的轉換出現(xiàn)問題。
Jackson對于復雜類型的bean轉換Json,轉換的json格式不是標準的Json格式
(2)jackson默認是序列化null對應的key的,也就是說不管你對象屬性有沒有值,在轉換json的時候都會被序列化出來
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException { AutoPartsSearchRequest request = new AutoPartsSearchRequest(); request.setKeywords("123"); request.setSortingField("234242"); ObjectMapper mapper = new ObjectMapper(); String str = mapper.writeValueAsString(request); System.out.println(str); //輸出結果(此處就不格式化了):{"sortingField":"234242","partsClassifyId":null,"partsSubClassifyId":null,"sortingDirection":null:...... }
2、同理,想要不序列化null也是可以的,具體如下:
1.實體上 @JsonInclude(Include.NON_NULL) //將該標記放在屬性上,如果該屬性為NULL則不參與序列化 //如果放在類上邊,那對這個類的全部屬性起作用 //Include.Include.ALWAYS 默認 //Include.NON_DEFAULT 屬性為默認值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化 2.代碼上 ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); //通過該方法對mapper對象進行設置,所有序列化的對象都將按改規(guī)則進行系列化 //Include.Include.ALWAYS 默認 //Include.NON_DEFAULT 屬性為默認值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化
注意:只對VO起作用,Map List不起作用,另外jackson還能過濾掉你設置的屬性,具體的就各位自己去研究源碼了
(3)pringboot默認使用Jackson ,@RestController注解,會采用HttpMessageConverter將數(shù)據(jù)進行轉換后寫入Response的body數(shù)據(jù)區(qū)
Jackson配置
引入maven
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.10.0</version> </dependency>
1. 通過在application.yml中進行jackson的對應配置去實現(xiàn)
spring: jackson: # 設置屬性命名策略,對應jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json駝峰式轉下劃線,json body下劃線傳到后端自動轉駝峰式 property-naming-strategy: SNAKE_CASE # 全局設置@JsonFormat的格式pattern date-format: yyyy-MM-dd HH:mm:ss # 當?shù)貢r區(qū) locale: zh # 設置全局時區(qū) time-zone: GMT+8 # 常用,全局設置pojo或被@JsonInclude注解的屬性的序列化方式 default-property-inclusion: NON_NULL #不為空的屬性才會序列化,具體屬性可看JsonInclude.Include # 常規(guī)默認,枚舉類SerializationFeature中的枚舉屬性為key,值為boolean設置jackson序列化特性,具體key請看SerializationFeature源碼 serialization: WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date轉換成timestamp FAIL_ON_EMPTY_BEANS: true # 對象為空時是否報錯,默認true # 枚舉類DeserializationFeature中的枚舉屬性為key,值為boolean設置jackson反序列化特性,具體key請看DeserializationFeature源碼 deserialization: # 常用,json中含pojo不存在屬性時是否失敗報錯,默認true FAIL_ON_UNKNOWN_PROPERTIES: false # 枚舉類MapperFeature中的枚舉屬性為key,值為boolean設置jackson ObjectMapper特性 # ObjectMapper在jackson中負責json的讀寫、json與pojo的互轉、json tree的互轉,具體特性請看MapperFeature,常規(guī)默認即可 mapper: # 使用getter取代setter探測屬性,如類中含getName()但不包含name屬性與setName(),傳輸?shù)膙o json格式模板中依舊含name屬性 USE_GETTERS_AS_SETTERS: true #默認false # 枚舉類JsonParser.Feature枚舉類中的枚舉屬性為key,值為boolean設置jackson JsonParser特性 # JsonParser在jackson中負責json內(nèi)容的讀取,具體特性請看JsonParser.Feature,一般無需設置默認即可 parser: ALLOW_SINGLE_QUOTES: true # 是否允許出現(xiàn)單引號,默認false # 枚舉類JsonGenerator.Feature枚舉類中的枚舉屬性為key,值為boolean設置jackson JsonGenerator特性,一般無需設置默認即可 # JsonGenerator在jackson中負責編寫json內(nèi)容,具體特性請看JsonGenerator.Feature
2.通過ObjectMapper 進行代碼配置實現(xiàn)
/** * 全局序列化配置類 */ @Configuration public class JsonConfig { /** * 創(chuàng)建Jackson對象映射器 * * @param builder Jackson對象映射器構建器 * @return ObjectMapper */ @Bean public ObjectMapper getJacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); //序列換成json時,將所有的long變成string.因為js中得數(shù)字類型不能包含所有的java long值,超過16位后會出現(xiàn)精度丟失 SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance); objectMapper.registerModule(simpleModule); //反序列化的時候如果多了其他屬性,不拋出異常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //日期格式處理 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); return objectMapper; } }
方式二、重寫configureMessageConverters方法
/** * 全局序列化配置類 */ @Configuration @EnableWebMvc public class JsonConfig implements WebMvcConfigurer { /** * 全局序列化方式 * * @param converters */ @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { //Jackson的全局序列化方式 configureJacksonHttpMessageConverter(converters); } /** * Jackson的全局序列化方式 * * @param converters */ private void configureJacksonHttpMessageConverter(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); //序列換成json時,將所有的long變成string.因為js中得數(shù)字類型不能包含所有的java long值,超過16位后會出現(xiàn)精度丟失 SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance); objectMapper.registerModule(simpleModule); //反序列化的時候如果多了其他屬性,不拋出異常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //日期格式處理 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); converter.setObjectMapper(objectMapper); converters.add(converter); converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); } }
ObjectMapper 常用工具類
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Jackson 工具類 * <p>Title: MapperUtils</p> * <p>Description: </p> * */ public class MapperUtils { private final static ObjectMapper objectMapper = new ObjectMapper(); public static ObjectMapper getInstance() { return objectMapper; } /** * 轉換為 JSON 字符串 * * @param obj * @return * @throws Exception */ public static String obj2json(Object obj) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); return mapper.writeValueAsString(obj); } /** * 轉換為 JSON 字符串,忽略空值 * * @param obj * @return * @throws Exception */ public static String obj2jsonIgnoreNull(Object obj) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); return mapper.writeValueAsString(obj); } /** * 轉換為 JavaBean * * @param jsonString * @param clazz * @return * @throws Exception */ public static <T> T json2pojo(String jsonString, Class<T> clazz) throws Exception { objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); return objectMapper.readValue(jsonString, clazz); } /** * 字符串轉換為 Map<String, Object> * * @param jsonString * @return * @throws Exception */ public static <T> Map<String, Object> json2map(String jsonString) throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); return mapper.readValue(jsonString, Map.class); } /** * 字符串轉換為 Map<String, T> */ public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws Exception { Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() { }); Map<String, T> result = new HashMap<String, T>(); for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) { result.put(entry.getKey(), map2pojo(entry.getValue(), clazz)); } return result; } /** * 深度轉換 JSON 成 Map * * @param json * @return */ public static Map<String, Object> json2mapDeeply(String json) throws Exception { return json2MapRecursion(json, objectMapper); } /** * 把 JSON 解析成 List,如果 List 內(nèi)部的元素存在 jsonString,繼續(xù)解析 * * @param json * @param mapper 解析工具 * @return * @throws Exception */ private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception { if (json == null) { return null; } List<Object> list = mapper.readValue(json, List.class); for (Object obj : list) { if (obj != null && obj instanceof String) { String str = (String) obj; if (str.startsWith("[")) { obj = json2ListRecursion(str, mapper); } else if (obj.toString().startsWith("{")) { obj = json2MapRecursion(str, mapper); } } } return list; } /** * 把 JSON 解析成 Map,如果 Map 內(nèi)部的 Value 存在 jsonString,繼續(xù)解析 * * @param json * @param mapper * @return * @throws Exception */ private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception { if (json == null) { return null; } Map<String, Object> map = mapper.readValue(json, Map.class); for (Map.Entry<String, Object> entry : map.entrySet()) { Object obj = entry.getValue(); if (obj != null && obj instanceof String) { String str = ((String) obj); if (str.startsWith("[")) { List<?> list = json2ListRecursion(str, mapper); map.put(entry.getKey(), list); } else if (str.startsWith("{")) { Map<String, Object> mapRecursion = json2MapRecursion(str, mapper); map.put(entry.getKey(), mapRecursion); } } } return map; } /** * 將 JSON 數(shù)組轉換為集合 * * @param jsonArrayStr * @param clazz * @return * @throws Exception */ public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception { JavaType javaType = getCollectionType(ArrayList.class, clazz); List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType); return list; } /** * 獲取泛型的 Collection Type * * @param collectionClass 泛型的Collection * @param elementClasses 元素類 * @return JavaType Java類型 * @since 1.0 */ public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) { return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); } /** * 將 Map 轉換為 JavaBean * * @param map * @param clazz * @return */ public static <T> T map2pojo(Map map, Class<T> clazz) { return objectMapper.convertValue(map, clazz); } /** * 將 Map 轉換為 JSON * * @param map * @return */ public static String mapToJson(Map map) { try { return objectMapper.writeValueAsString(map); } catch (Exception e) { e.printStackTrace(); } return ""; } /** * 將 JSON 對象轉換為 JavaBean * * @param obj * @param clazz * @return */ public static <T> T obj2pojo(Object obj, Class<T> clazz) { return objectMapper.convertValue(obj, clazz); } }
到此這篇關于Java中對象 和 json 互轉 四種方式 json-lib、Gson、FastJson、Jackson的文章就介紹到這了,更多相關對象和json互轉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Jackson使用示例-Bean、XML、Json之間相互轉換
- 一篇文章了解Jackson注解@JsonFormat及失效解決辦法
- 利用Jackson解決Json序列化和反序列化問題
- Java利用Jackson輕松處理JSON序列化與反序列化
- Jackson中json格式的字符串與對象的互相轉換方式
- 如何自定義Jackson序列化?@JsonSerialize
- JSON中fastjson、jackson、gson如何選擇
- jackson 如何將實體轉json json字符串轉實體
- 使用jackson實現(xiàn)對象json之間的相互轉換(spring boot)
- 使用Jackson-json解析一個嵌套的json字符串
- Jackson庫進行JSON?序列化時遇到了無限遞歸(Infinite?Recursion)的問題及解決方案
相關文章
如何通過RabbitMq實現(xiàn)動態(tài)定時任務詳解
工作中經(jīng)常會有定時任務的需求,常見的做法可以使用Timer、Quartz、Hangfire等組件,這次想嘗試下新的思路,使用RabbitMQ死信隊列的機制來實現(xiàn)定時任務,下面這篇文章主要給大家介紹了關于如何通過RabbitMq實現(xiàn)動態(tài)定時任務的相關資料,需要的朋友可以參考下2022-01-01SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法
這篇文章主要介紹了SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08Springboot全局異常捕獲及try catch區(qū)別解析
這篇文章主要介紹了Springboot全局異常捕獲及try catch區(qū)別解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06基于JavaMail的Java實現(xiàn)復雜郵件發(fā)送功能
這篇文章主要為大家詳細介紹了基于JavaMail的Java實現(xiàn)復雜郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09Spring Cloud Gateway組件的三種使用方式實例詳解
Spring Cloud Gateway是 Spring 官方基于 Spring5.0 、 SpringBoot2.0 和 Project Reactor 等技術開發(fā)的網(wǎng)關旨在為微服務框架提供一種簡單而有效的統(tǒng)一的API 路由管理方式,統(tǒng)一訪問接口,這篇文章主要介紹了Spring Cloud Gateway組件的三種使用方式,需要的朋友可以參考下2024-01-01