Java中對象?和?json?互轉(zhuǎn)四種方式?json-lib、Gson、FastJson、Jackson
一、 json-lib
json-lib最開始的也是應(yīng)用最廣泛的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,
對于復(fù)雜類型的轉(zhuǎn)換,json-lib對于json轉(zhuǎn)換成bean還有缺陷,比如一個類里面會出現(xiàn)另一個類的list或者map集合,json-lib從json到bean的轉(zhuǎn)換就會出現(xiàn)問題。
json-lib在功能和性能上面都不能滿足現(xiàn)在互聯(lián)網(wǎng)化的需求。
二、 Google的Gson
1.簡介
(1)Gson是目前功能最全的Json解析神器,Gson當(dāng)初是為因應(yīng)Google公司內(nèi)部需求而由Google自行研發(fā)而來 但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用。
Gson的應(yīng)用主要為toJson與fromJson兩個轉(zhuǎn)換函數(shù),無依賴,不需要例外額外的jar,能夠直接跑在JDK上。
而在使用這種對象轉(zhuǎn)換之前需先創(chuàng)建好對象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對應(yīng)的對象。
類里面只要有g(shù)et和set方法,Gson完全可以將復(fù)雜類型的json到bean或bean到j(luò)son的轉(zhuǎn)換,是JSON解析的神器。
Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距。
(2)默認(rèn)是不序列化null值對應(yīng)的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);
//輸出結(jié)果:{"sortingField":"234242","keywords":"123"}
}若是想序列化null值對應(yīng)的key,只需要將以上創(chuàng)建代碼改成以下代碼就行:
Gson g = new GsonBuilder().serializeNulls().create();
若是想轉(zhuǎn)行null為空字符串"",則需要手動處理了
(3)主要類介紹
Gson類:解析json的最基礎(chǔ)的工具類
JsonParser類:解析器來解析JSON到JsonElements的解析樹
JsonElement類:一個類代表的JSON元素
JsonObject類:JSON對象類型
JsonArray類:JsonObject數(shù)組
TypeToken類:用于創(chuàng)建type,比如泛型List<?>
(4)bean轉(zhuǎn)換json
Gson gson = new Gson(); String json = gson.toJson(obj); //obj是對象
(5) json轉(zhuǎn)換bean
Gson gson = new Gson();
String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = gson.fromJson(json, Book.class);(6) json轉(zhuǎn)換復(fù)雜的bean,比如List,Set
將json轉(zhuǎn)換成復(fù)雜類型的bean,需要使用TypeToken
Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = gson.fromJson(json,new TypeToken<LIST>() {}.getType());
//將json轉(zhuǎn)換成Set
Set set = gson.fromJson(json,new TypeToken<SET>() {}.getType());(7) 通過json對象直接操作json以及一些json的工具
a) 格式化Json
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
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技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
boolean jsonFlag;
try {
new JsonParser().parse(str).getAsJsonObject();
jsonFlag = true;
} catch (Exception e) {
jsonFlag = false;
}c) 從json串中獲取屬性
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
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技術(shù)\"}";
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技術(shù)\"}";
String propertyName = 'desc';
Object propertyValue = "json各種技術(shù)的調(diào)研";
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技術(shù)\"}";
String propertyName = 'name';
Object propertyValue = "json各種技術(shù)的調(diào)研";
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技術(shù)\"}";
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類的對象,就會按照設(shè)置的格式進行處理
i) json中對于Html的轉(zhuǎn)義
Gson gson = new Gson();
這種對象默認(rèn)對Html進行轉(zhuǎn)義,如果不想轉(zhuǎn)義使用下面的方法
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在復(fù)雜類型的Bean轉(zhuǎn)換Json上會出現(xiàn)一些問題,可能會出現(xiàn)引用的類型,導(dǎo)致Json轉(zhuǎn)換出錯,需要制定引用。
FastJson采用獨創(chuàng)的算法,將parse的速度提升到極致,超過所有json庫。
(2)fastJson在轉(zhuǎn)換java對象為json的時候,默認(rèn)是不序列化null值對應(yīng)的key的,也就是說當(dāng)對象里面的屬性為空的時候,在轉(zhuǎn)換成json時,不序列化那些為null值的屬性
但是如果想把null對應(yīng)的key序列化出來呢?
那就要仔細看看fastjson轉(zhuǎn)換java對象為json的時候的入?yún)⒘耍阂簿褪沁@個方法:
JSONObject.toJSONString(Object object, SerializerFeature… features)
Fastjson的SerializerFeature序列化屬性:
QuoteFieldNames———-輸出key時是否使用雙引號,默認(rèn)為true WriteMapNullValue——–是否輸出值為null的字段,默認(rèn)為false WriteNullNumberAsZero—-數(shù)值字段如果為null,輸出為0,而非null WriteNullListAsEmpty—–List字段如果為null,輸出為[],而非null WriteNullStringAsEmpty—字符類型字段如果為null,輸出為”“,而非null WriteNullBooleanAsFalse–Boolean字段如果為null,輸出為false,而非null
結(jié)合上面,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轉(zhuǎn)換json將對象轉(zhuǎn)換成格式化的json
JSON.toJSONString(obj,true);
(4)將對象轉(zhuǎn)換成非格式化的json
JSON.toJSONString(obj,false);
obj設(shè)計對象
對于復(fù)雜類型的轉(zhuǎn)換,對于重復(fù)的引用在轉(zhuǎn)成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轉(zhuǎn)換bean
String json = "{\"id\":\"2\",\"name\":\"Json技術(shù)\"}";
Book book = JSON.parseObject(json, Book.class);(6) json轉(zhuǎn)換復(fù)雜的bean,比如List,Map
String json = "[{\"id\":\"1\",\"name\":\"Json技術(shù)\"},{\"id\":\"2\",\"name\":\"java技術(shù)\"}]";
//將json轉(zhuǎn)換成List
List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){});
//將json轉(zhuǎn)換成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技術(shù)\"}";
JSONObject obj = JSON.parseObject(json);
propertyValue = obj.get(propertyName));b) 除去json中的某個屬性
String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技術(shù)\"}";
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技術(shù)\"}";
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技術(shù)\"}";
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技術(shù)\"}";
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");
//設(shè)置序列化特征
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);
// 配置添加到消息轉(zhuǎn)換器里面
converter.setFastJsonConfig(fastJsonConfig);
converter.setDefaultCharset(Charset.forName("UTF-8"));
// 設(shè)置響應(yīng)JSON格式數(shù)據(jù)
List<MediaType> mediaTypeList = new ArrayList<>();
mediaTypeList.add(MediaType.APPLICATION_JSON);
// 設(shè)置消息轉(zhuǎn)換器支持的格式
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;
}
}測試結(jié)果:

注意: fastJson 引用2.0.17 版本后 日期格式話失敗,退回到1.2.83 版本后正常。
4. 開源的Jackson 簡介:
(1)相比json-lib框架,Jackson所依賴的jar包較少,簡單易用并且性能也要相對高些。
而且Jackson社區(qū)相對比較活躍,更新速度也比較快。
Jackson對于復(fù)雜類型的json轉(zhuǎn)換bean會出現(xiàn)問題,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問題。
Jackson對于復(fù)雜類型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標(biāo)準(zhǔn)的Json格式
(2)jackson默認(rèn)是序列化null對應(yīng)的key的,也就是說不管你對象屬性有沒有值,在轉(zhuǎn)換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);
//輸出結(jié)果(此處就不格式化了):{"sortingField":"234242","partsClassifyId":null,"partsSubClassifyId":null,"sortingDirection":null:......
}2、同理,想要不序列化null也是可以的,具體如下:
1.實體上 @JsonInclude(Include.NON_NULL) //將該標(biāo)記放在屬性上,如果該屬性為NULL則不參與序列化 //如果放在類上邊,那對這個類的全部屬性起作用 //Include.Include.ALWAYS 默認(rèn) //Include.NON_DEFAULT 屬性為默認(rèn)值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化 2.代碼上 ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_NULL); //通過該方法對mapper對象進行設(shè)置,所有序列化的對象都將按改規(guī)則進行系列化 //Include.Include.ALWAYS 默認(rèn) //Include.NON_DEFAULT 屬性為默認(rèn)值不序列化 //Include.NON_EMPTY 屬性為 空(“”) 或者為 NULL 都不序列化 //Include.NON_NULL 屬性為NULL 不序列化
注意:只對VO起作用,Map List不起作用,另外jackson還能過濾掉你設(shè)置的屬性,具體的就各位自己去研究源碼了
(3)pringboot默認(rèn)使用Jackson ,@RestController注解,會采用HttpMessageConverter將數(shù)據(jù)進行轉(zhuǎn)換后寫入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的對應(yīng)配置去實現(xiàn)
spring:
jackson:
# 設(shè)置屬性命名策略,對應(yīng)jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json駝峰式轉(zhuǎn)下劃線,json body下劃線傳到后端自動轉(zhuǎn)駝峰式
property-naming-strategy: SNAKE_CASE
# 全局設(shè)置@JsonFormat的格式pattern
date-format: yyyy-MM-dd HH:mm:ss
# 當(dāng)?shù)貢r區(qū)
locale: zh
# 設(shè)置全局時區(qū)
time-zone: GMT+8
# 常用,全局設(shè)置pojo或被@JsonInclude注解的屬性的序列化方式
default-property-inclusion: NON_NULL #不為空的屬性才會序列化,具體屬性可看JsonInclude.Include
# 常規(guī)默認(rèn),枚舉類SerializationFeature中的枚舉屬性為key,值為boolean設(shè)置jackson序列化特性,具體key請看SerializationFeature源碼
serialization:
WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date轉(zhuǎn)換成timestamp
FAIL_ON_EMPTY_BEANS: true # 對象為空時是否報錯,默認(rèn)true
# 枚舉類DeserializationFeature中的枚舉屬性為key,值為boolean設(shè)置jackson反序列化特性,具體key請看DeserializationFeature源碼
deserialization:
# 常用,json中含pojo不存在屬性時是否失敗報錯,默認(rèn)true
FAIL_ON_UNKNOWN_PROPERTIES: false
# 枚舉類MapperFeature中的枚舉屬性為key,值為boolean設(shè)置jackson ObjectMapper特性
# ObjectMapper在jackson中負(fù)責(zé)json的讀寫、json與pojo的互轉(zhuǎn)、json tree的互轉(zhuǎn),具體特性請看MapperFeature,常規(guī)默認(rèn)即可
mapper:
# 使用getter取代setter探測屬性,如類中含getName()但不包含name屬性與setName(),傳輸?shù)膙o json格式模板中依舊含name屬性
USE_GETTERS_AS_SETTERS: true #默認(rèn)false
# 枚舉類JsonParser.Feature枚舉類中的枚舉屬性為key,值為boolean設(shè)置jackson JsonParser特性
# JsonParser在jackson中負(fù)責(zé)json內(nèi)容的讀取,具體特性請看JsonParser.Feature,一般無需設(shè)置默認(rèn)即可
parser:
ALLOW_SINGLE_QUOTES: true # 是否允許出現(xiàn)單引號,默認(rèn)false
# 枚舉類JsonGenerator.Feature枚舉類中的枚舉屬性為key,值為boolean設(shè)置jackson JsonGenerator特性,一般無需設(shè)置默認(rèn)即可
# JsonGenerator在jackson中負(fù)責(zé)編寫json內(nèi)容,具體特性請看JsonGenerator.Feature2.通過ObjectMapper 進行代碼配置實現(xiàn)
/**
* 全局序列化配置類
*/
@Configuration
public class JsonConfig {
/**
* 創(chuàng)建Jackson對象映射器
*
* @param builder Jackson對象映射器構(gòu)建器
* @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;
}
/**
* 轉(zhuǎn)換為 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);
}
/**
* 轉(zhuǎn)換為 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);
}
/**
* 轉(zhuǎn)換為 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);
}
/**
* 字符串轉(zhuǎn)換為 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);
}
/**
* 字符串轉(zhuǎn)換為 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;
}
/**
* 深度轉(zhuǎn)換 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ù)組轉(zhuǎn)換為集合
*
* @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 轉(zhuǎn)換為 JavaBean
*
* @param map
* @param clazz
* @return
*/
public static <T> T map2pojo(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
/**
* 將 Map 轉(zhuǎn)換為 JSON
*
* @param map
* @return
*/
public static String mapToJson(Map map) {
try {
return objectMapper.writeValueAsString(map);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 將 JSON 對象轉(zhuǎn)換為 JavaBean
*
* @param obj
* @param clazz
* @return
*/
public static <T> T obj2pojo(Object obj, Class<T> clazz) {
return objectMapper.convertValue(obj, clazz);
}
}到此這篇關(guān)于Java中對象 和 json 互轉(zhuǎn) 四種方式 json-lib、Gson、FastJson、Jackson的文章就介紹到這了,更多相關(guān)對象和json互轉(zhuǎn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Jackson使用示例-Bean、XML、Json之間相互轉(zhuǎn)換
- 一篇文章了解Jackson注解@JsonFormat及失效解決辦法
- 利用Jackson解決Json序列化和反序列化問題
- Java利用Jackson輕松處理JSON序列化與反序列化
- Jackson中json格式的字符串與對象的互相轉(zhuǎn)換方式
- 如何自定義Jackson序列化?@JsonSerialize
- JSON中fastjson、jackson、gson如何選擇
- jackson 如何將實體轉(zhuǎn)json json字符串轉(zhuǎn)實體
- 使用jackson實現(xiàn)對象json之間的相互轉(zhuǎn)換(spring boot)
- 使用Jackson-json解析一個嵌套的json字符串
- Jackson庫進行JSON?序列化時遇到了無限遞歸(Infinite?Recursion)的問題及解決方案
相關(guān)文章
如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)詳解
工作中經(jīng)常會有定時任務(wù)的需求,常見的做法可以使用Timer、Quartz、Hangfire等組件,這次想嘗試下新的思路,使用RabbitMQ死信隊列的機制來實現(xiàn)定時任務(wù),下面這篇文章主要給大家介紹了關(guān)于如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)的相關(guān)資料,需要的朋友可以參考下2022-01-01
SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法
這篇文章主要介紹了SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
Springboot全局異常捕獲及try catch區(qū)別解析
這篇文章主要介紹了Springboot全局異常捕獲及try catch區(qū)別解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
基于JavaMail的Java實現(xiàn)復(fù)雜郵件發(fā)送功能
這篇文章主要為大家詳細介紹了基于JavaMail的Java實現(xiàn)復(fù)雜郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Spring Cloud Gateway組件的三種使用方式實例詳解
Spring Cloud Gateway是 Spring 官方基于 Spring5.0 、 SpringBoot2.0 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān)旨在為微服務(wù)框架提供一種簡單而有效的統(tǒng)一的API 路由管理方式,統(tǒng)一訪問接口,這篇文章主要介紹了Spring Cloud Gateway組件的三種使用方式,需要的朋友可以參考下2024-01-01

