Java中Json字符串和Java對(duì)象的互轉(zhuǎn)
JSON(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式。誕生于 2002 年。易于人閱讀和編寫。同時(shí)也易于機(jī)器解析和生成。JSON 是目前主流的前后端數(shù)據(jù)傳輸方式。
JSON 采用完全獨(dú)立于語言的文本格式,但是也使用了類似于 C 語言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使 JSON 成為理想的數(shù)據(jù)交換語言。幾乎所有的APP、應(yīng)用、網(wǎng)站、程序都離不開 JSON。
常見的 Json 解析器:Gson,F(xiàn)astjson,Json-lib,Jackson
一、Java中Json字符串和Java對(duì)象的互轉(zhuǎn)概述
1、關(guān)于 Json
Json(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式。誕生于 2002 年。易于人閱讀和編寫。同時(shí)也易于機(jī)器解析和生成。Json 是目前主流的前后端數(shù)據(jù)傳輸方式。
Json 采用完全獨(dú)立于語言的文本格式,但是也使用了類似于 C 語言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使 Json 成為理想的數(shù)據(jù)交換語言。幾乎所有的APP、應(yīng)用、網(wǎng)站、程序都離不開 Json。
2、Json 解析器
常見的 Json 解析器:Gson,F(xiàn)astJson,Json-lib,Jackson
- Gson(又稱Google Gson)是 Google 公司發(fā)布的一個(gè)開放源代碼的 Java 庫(kù)。特點(diǎn)是快速高效,代碼量少、簡(jiǎn)潔;
- FastJson 是一個(gè)Java語言編寫的高性能的 Json 處理器,由阿里巴巴公司開發(fā)。無依賴,不需要例外額外的 Jar,能夠直接跑在 Jdk 上;
- Json-lib 最開始的也是應(yīng)用最廣泛的 Json 解析工具,Json-lib 不好的地方確實(shí)是依賴于很多第三方包;
- 相比 Json-lib 框架,Jackson 所依賴的 Jar 包較少,簡(jiǎn)單易用并且性能也要相對(duì)高些。而且 Jackson 社區(qū)相對(duì)比較活躍,更新速度也比較快。Jackson 對(duì)于復(fù)雜類型的 Json 轉(zhuǎn)換Bean 會(huì)出現(xiàn)問題,一些集合 Map,List 的轉(zhuǎn)換出現(xiàn)問題。
序列化性能:FastJson > Jackson > Gson > Jsonlib
反序列化性能:Gson > Jackson > FastJson > Jsonlib
二、使用 Gson 完成 Json 字符串和 Java 對(duì)象的互轉(zhuǎn)
1、Gson 介紹
Google 的 Gson 是目前功能最全的 Json 解析神器,Gson 當(dāng)初是為因應(yīng) Google 公司內(nèi)部需求而由 Google 自行研發(fā),但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應(yīng)用。
Gson 的應(yīng)用主要為 toJson 與 fromJson 兩個(gè)轉(zhuǎn)換函數(shù),無依賴,不需要例外額外的 Jar,能夠直接跑在 Jdk 上。而在使用這種對(duì)象轉(zhuǎn)換之前需先創(chuàng)建好對(duì)象的類型以及其成員才能成功的將Json 字符串成功轉(zhuǎn)換成相對(duì)應(yīng)的對(duì)象。類里面只要有 get 和 set 方法,Gson 完全可以將復(fù)雜類型的 Json 到 Bean 或 Bean 到 Json 的轉(zhuǎn)換,是 Json 解析的神器。
Ps:盡管 Gson 在功能上面無可挑剔,但是性能上面比 FastJson 有所差距。
2、Gson 引入
Maven 依賴引入:
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
3、Gson 主要類介紹
Gson 主要類:
- Gson 類:解析 Json 的最基礎(chǔ)的工具類
- JsonParser 類:解析器來解析 Json 到 JsonElements 的解析樹
- JsonElement 類:一個(gè)類代表的 Json 元素
- JsonObject 類:Json 對(duì)象類型
- JsonArray 類:JsonObject 數(shù)組
- TypeToken 類:用于創(chuàng)建 type,比如泛型 List<?>
4、Gson Demo
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonTestClass {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("栗箏i");
Gson g = new GsonBuilder().create();
String str = g.toJson(user);
System.out.println(str);
}
}
Ps:默認(rèn)是不序列化 null 值對(duì)應(yīng)的 key 的,若是想序列化 null 值對(duì)應(yīng)的 key,只需要將以上創(chuàng)建代碼改成以下代碼就行:
Gson g = new GsonBuilder().serializeNulls().create();
5、對(duì)象與 Json 互轉(zhuǎn)
# bean 轉(zhuǎn)換 Json
Gson gson = new Gson(); // obj 是對(duì)象 String json = gson.toJson(obj);
Ps:當(dāng)我們需要把定義類的成員變量屬性名和返回的 Json 中的格式名稱隔離開,可以采用 @SerializedName 注解標(biāo)記??!
# Json 轉(zhuǎn)換 bean
Gson gson = new Gson();
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
Book book = gson.fromJson(json, Book.class);
# Json 轉(zhuǎn)換復(fù)雜的 bean,比如 List,Set
Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"栗箏i\"},{\"id\":\"2\",\"name\":\"栗箏ii\"}]";
// 將 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());
6、直接操作 Json 以及一些 Json 的工具
# 格式化 Json:
String json = "[{\"id\":\"1\",\"name\":\"栗箏i\"},{\"id\":\"2\",\"name\":\"栗箏ii\"}]";
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(json);
json = gson.toJson(je);
# 判斷字符串是否是 Json(通過捕捉的異常來判斷是否是 Json)
String json = "[{\"id\":\"1\",\"name\":\"栗箏i\"},{\"id\":\"2\",\"name\":\"栗箏ii\"}]";
boolean jsonFlag;
try {
new JsonParser().parse(str).getAsJsonObject();
jsonFlag = true;
} catch (Exception e) {
jsonFlag = false;
}
# 從 Json 串中獲取屬性
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
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;
}
# 除去 Json 中的某個(gè)屬性
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
String propertyName = 'id';
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
json = jsonObj.toString();
# 向 Json 中添加屬性
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
String propertyName = 'age';
Object propertyValue = "26";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();
# 修改 Json 中的屬性
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
String propertyName = 'name';
Object propertyValue = "栗箏ii";
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();
# 判斷 Json 中是否有屬性
String json = "{\"id\":\"1\",\"name\":\"栗箏i\"}";
String propertyName = 'name';
boolean isContains = false ;
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
isContains = jsonObj.has(propertyName);
7、gsonUtil 工具類
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;
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);
}
}
三、使用 FastJson 完成 Json 字符串和 Java 對(duì)象的互轉(zhuǎn)
1、FastJson 介紹
Fastjson 由阿里巴巴公司開發(fā),是一個(gè) Java 語言編寫的高性能的 Json 處理器。無依賴,不需要例外額外的 Jar,能夠直接跑在 Jdk 上。
FastJson 在復(fù)雜類型的 Bean 轉(zhuǎn)換 Json 上會(huì)出現(xiàn)一些問題,可能會(huì)出現(xiàn)引用的類型,導(dǎo)致 Json 轉(zhuǎn)換出錯(cuò),需要制定引用。
FastJson 采用獨(dú)創(chuàng)的算法,將 parse 的速度提升到極致,超過所有 Json 庫(kù)。
2、FastJson 引入
Maven 依賴引入:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.23</version>
</dependency>
3、null 值對(duì)應(yīng) key 的序列化
FastJson 在轉(zhuǎn)換 Java 對(duì)象為 Json 的時(shí)候,默認(rèn)是不序列化 null 值對(duì)應(yīng)的 key 的,也就是說當(dāng)對(duì)象里面的屬性為空的時(shí)候,在轉(zhuǎn)換成 Json 時(shí),不序列化那些為 null 值的屬性
仔細(xì)看 FastJson 轉(zhuǎn)換 Java 對(duì)象為 Json 的方法的入?yún)ⅲ?/p>
public static String toJSONString(Object object, com.alibaba.fastjson2.JSONWriter.Feature... features)
可以看到 features 是一個(gè)數(shù)組 JSONWriter.Feature 則是其序列化屬性:
- QuoteFieldNames———-輸出 key 時(shí)是否使用雙引號(hào),默認(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
4、FastJson Demo
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
public class FastJsonTestClass {
public static void main(String[] args) {
User user = new User();
user.setIdd(1);
user.setName("栗箏i");
String str = JSONObject.toJSONString(user, JSONWriter.Feature.WriteMapNullValue);
System.out.println(str);
}
}
Ps:當(dāng)我們需要把定義類的成員變量屬性名和返回的 Json 中的格式名稱隔離開,可以采用 @JSONField 注解標(biāo)記??!
5、對(duì)象與 Json 互轉(zhuǎn)
# 對(duì)象轉(zhuǎn) Json
User user = new User();
user.setId(1);
user.setName("栗箏i");
System.out.println(JSON.toJSONString(user, JSONWriter.Feature.UseSingleQuotes));
# Json 轉(zhuǎn)對(duì)象
String json = "{\"id\":1,'name':'張三'}";
User userModel = JSON.parseObject(json, User.class);
# 將 Json 解析為 JSONObject
String json = "{\"id\":1,'name':'張三'}";
JSONObject data = JSON.parseObject(json);
System.out.println(data.get("id"));
# 將 Json 解析為 JSONArray
String text = "..."; JSONArray data = JSON.parseArray(text);
到此這篇關(guān)于Java中Json字符串和Java對(duì)象的互轉(zhuǎn)的文章就介紹到這了,更多相關(guān)Java Json和Java對(duì)象互轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java中常用的json,jsonarray,map數(shù)據(jù)結(jié)構(gòu)與對(duì)象互轉(zhuǎn)詳解
- Java中對(duì)象?和?json?互轉(zhuǎn)四種方式?json-lib、Gson、FastJson、Jackson
- java中json和對(duì)象之間相互轉(zhuǎn)換的運(yùn)用
- JAVA中JSONObject對(duì)象和Map對(duì)象之間的相互轉(zhuǎn)換
- Java實(shí)現(xiàn)Json字符串與Object對(duì)象相互轉(zhuǎn)換的方式總結(jié)
- 詳談Java中net.sf.json包關(guān)于JSON與對(duì)象互轉(zhuǎn)的坑
- 基于JSON和java對(duì)象的互轉(zhuǎn)方法
- java對(duì)象與json對(duì)象間的相互轉(zhuǎn)換的方法
- java中實(shí)體類和JSON對(duì)象之間相互轉(zhuǎn)化
相關(guān)文章
帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之棧
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之棧 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
springboot高并發(fā)下提高吞吐量的實(shí)現(xiàn)
這篇文章主要介紹了springboot高并發(fā)下提高吞吐量的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id
這篇文章主要介紹了如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
Java文件字符輸入流FileReader讀取txt文件亂碼的解決
這篇文章主要介紹了Java文件字符輸入流FileReader讀取txt文件亂碼的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Java中的字節(jié),字符輸出流與字節(jié)和字符輸入流的簡(jiǎn)單理解
這篇文章主要介紹了java 字節(jié)流和字符流的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-07-07
Spring Boot中保存前端上傳的圖片實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了Spring Boot中保存前端上傳的圖片實(shí)現(xiàn)步驟,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2025-06-06

