公衆號:小李不禿,Java 原創博主閱讀本文大概須要 7.8 分鐘javascript
咱們在進行軟件開發的過程當中,服務與服務之間會進行相互的調用。在數據進行傳輸前,咱們一般會將數據轉化成 JSON 的格式進行傳輸,好比 ajax 調用請求,接收傳過來的 JSON 數據,javascript 就能夠對傳過來的數據進行直接的調用。html
本篇文章會講解如下的內容:java
如何使用 JSON---Howgit
JSON 全拼 Java Script Object Notation,JavaScript 對象表示法。是一種由道格拉斯·克羅克福特構想和設計、輕量級的數據交換語言,該語言以易於讓人閱讀的文字爲基礎,用來傳輸由屬性值或者序列性的值組成的數據對象。儘管 JSON 是 JavaScript 的子集,可是 JSON 是獨立於語言的文本格式。github
JSON 數據格式與語言無關。即使它源自 JavaScript,但不少編程語言都支持 JSON 格式數據的生成和解析,例如在 Java 中就有 fastjson、gson 等工具類對 JSON 進行操做。ajax
小結:express
提到這裏,就不得不和 XML 進行比較了。XML 也是能夠做爲跨平臺的數據交換格式。可是爲何咱們大多用 JSON,而不用 XML 呢?有下面幾點緣由:編程
對於 AJAX 應用程序來講,JSON 比 XML 更快更易使用。json
綜上,咱們更傾向於選擇 JSON 來進行數據交換。segmentfault
JSON 對象使用在 大括號「{}」中書寫,對象能夠有多個鍵值對(key/value)。
key 必須是字符串,value 能夠是合法的 JSON 數據類型(字符串、數字、對象、數組、布爾值或null)
key 和 value 中使用冒號「:」分割,鍵值對之間用逗號「,」分割。
{"name":"關注公衆號:小李不禿","age":18,"money":null}
JSON 數組在中括號「[]」中書寫。JSON 中數組值必須是合法的 JSON 數據類型。
[ {"name":"張三"}, {"name":"李四"), {"name":"王五"} ]
可使用點號「.」來訪問對象的值,也可使用中括號「[]」來訪問對象的值。
var data, x; data = {"name":"xiaoli", "area":"china", "money":null}; x = data.name; #或者myObj["name"] 運行結果:xiaoli
使用 for-in 來循環對象的屬性
var data, x; data = {"name":"xiaoli", "area":"china", "money":null}; for(x in data){ console.log(x + ":" + data[x]); } 運行結果: name:xiaoli area:china money:null
可使用點號「.」來修改 JSON 對象的值,也可使用中括號「[]」修改 JSON 對象的值。
data.money = 100; data["money"] = 100;
經過 delete 關鍵字來刪除 JSON 對象的屬性。
delete data.money; delete data["money"]
經過索引值來訪問數組。
var myObj, x; myObj = { "name":"網站", "num":3, "sites":[ "Google", "Runoob", "Taobao" ] } x = myObj.sites[0]; 運行結果:Google
經過 for-in 來訪問數組。
var myObj, i, x = ""; myObj = { "name":"網站", "num":3, "sites":[ "Google", "Runoob", "Taobao" ] }; for (i in myObj.sites) { x += myObj.sites[i] + "<br>"; } 運行結果: Google Runoob Taobao
也能夠經過 for 來循環訪問數組。
var myObj, i, x = ""; myObj = { "name":"網站", "num":3, "sites":[ "Google", "Runoob", "Taobao" ] }; for (i = 0; i < myObj.sites.length; i++) { x += myObj.sites[i] + "<br>"; }
javaScript 中的 for-in 相似於 Java 中的 foreach 。
能夠經過索引值來修改數組元素。
myObj.sites[1] = "Github";
使用 delete 來刪除數組元素
delete myObj.sites[1];
這裏須要注意 delete 並無完全刪除元素,而是刪除它的值,仍然會保留空間。運算符 delete 只是將該值設置爲 undefined,而不會影響數組的長度。若是想要實現完全刪除,須要使用 splice() 方法。
var myObj, i, x = ""; myObj = { "name":"網站", "num":3, "sites":[ "Google", "Runoob", "Taobao" ] }; delete myObj.sites[1]; x = "sites.length = " + myObj.sites.length + "<br><br>"; for (i=0;i<myObj.sites.length;i++) { console.log(i + ":" + myObj.sites[i]); x += i + " " + myObj.sites[i] + "<br>"; } document.getElementById("demo").innerHTML = x; 運行結果: 0:Google 1:undefined 2:Taobao
myObj.sites.splice(1,1); 運行結果: 0:Google 1:Taobao
JSON 一般與服務端交換數據,接收服務器傳輸的數據時通常是字符串,咱們能夠經過 JSON.parse() 方法將數據轉換爲 JavaScipt 對象。
具體使用
var obj = JSON.parse('{"name":"關注公衆號:小李不禿","age":18,"money":null}'); console.log(obj.name + ":" + obj.age + ":" + obj.money) 運行結果:關注公衆號:小李不禿:18:null
JSON 存 Date 對象,須要將其轉換爲字符串,以後再將字符串轉換爲 Date 對象。
var text = '{ "name":"小李不禿", "initDate":"2020-1-17"}'; var obj = JSON.parse(text, function (key, value) { if (key == "initDate") { return new Date(value); } else { return value; }}); console.log(obj.name + ":" + obj.initDate); 運行結果:小李不禿:Fri Jan 17 2020 00:00:00 GMT+0800 (中國標準時間)
JSON 在向服務端傳輸的數據通常是字符串,因此咱們可使用 JSON.stringify() 方法將 JavaScript 對象轉換爲字符串。
具體使用
var obj = {"name":"xiaoli", "area":"china", "money":null}; console.log(obj); var myJSON = JSON.stringify(obj); console.log(myJSON);
運行結果
對於服務器返回的 JSON 字符串,若是 jQuery 異步請求沒作類型說明,或者以字符串方式接收,那麼須要作一次對象化處理,方式不是太麻煩,就是將該字符串放於 eval() 中執行一次。這種方式也適合以普通 javascipt 方式獲取 json 對象,如下舉例說明:
var u = eval('('+user+')');
爲何要 eval 這裏要添加 ('('+user+')') 呢?
緣由在於:eval 自己的問題。 因爲 json 是以 {} 的方式來開始以及結束的,在 js 中,它會被當成一個語句塊來處理,因此必須強制性的將它轉換成一種表達式。
加上圓括號的目的是迫使 eval 函數在處理 JavaScript 代碼的時候強制將括號內的表達式(expression)轉化爲對象,而不是做爲語句(statement)來執行。舉一個例子,例如對象字面量 {},如若不加外層的括號,那麼 eval 會將大括號識別爲 javascript 代碼塊的開始和結束標記,那麼{}將會被認爲是執行了一句空語句。因此下面兩個執行結果是不一樣的:
alert(eval("{}"); // return undefined alert(eval("({})");// return object[Object]
測試用例
var user = '{"name":"關注公衆號:小李不禿","age":18,"money":null,'+ 'showInfo:function(){'+ 'document.write("姓名:"+this.name+"<br/>");'+ 'document.write("年齡:"+this.age+"<br/>");'+ 'document.write("金錢:"+this.money+"<br/>");}}'; var u = eval('('+user+')'); u.showInfo(); 運行結果: 姓名:關注公衆號:小李不禿 年齡:18 金錢:null
在 Java 中,解析 JSON 的第三方工具類有不少,經常使用的有幾種:
統一用下面的 Person 類做爲示例
@Data public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } }
那咱們對這幾個工具類進行一一介紹:
Json-lib 是一個 Java 類庫,提供將 Java 對象(包括:beans,maps,collections,java arrays 和 XML等)和 JSON 互相轉換的功能。
引入相關 jar 包
Json-lib 工具類
封裝一個 Json-lib 工具類,方便測試用。
// Json-lib 工具類 public class JsonLibUtils { /** * bean 轉換爲 Json 字符串 */ public static String bean2json(Object o){ JSONObject jsonObject = JSONObject.fromObject(o); return jsonObject.toString(); } /** * json 轉換爲 bean */ public static Object json2bean(String s,Class c){ JSONObject jsonObject = JSONObject.fromObject(s); return JSONObject.toBean(jsonObject,c); } /** * list 轉換爲 Json 字符串 */ public static String list2json(List list){ JSONArray jsonArray = JSONArray.fromObject(list); return jsonArray.toString(); } /** * json 轉換爲 list */ public static List json2List(String s){ return JSONArray.fromObject(s); } /** * set 轉換爲 Json 字符串 */ public static String set2json(Set set){ JSONArray jsonArray = JSONArray.fromObject(set); return jsonArray.toString(); } /** * json 轉換爲 set */ public static Set json2Set(String json) { Set<Person> set = new HashSet<>(json2List(json)); return set; } /** * map 轉換爲 Json 字符串 */ public static String map2json(Map map){ JSONObject jsonObject = JSONObject.fromObject(map); return jsonObject.toString(); } /** * json 轉換爲 map */ public static Map<Object, Object> json2Map(String json) { JSONObject jsonObject = JSONObject.fromObject(json); Map<Object, Object> map = (Map)jsonObject; return map; } }
示例代碼:
public class JsonlibTest { public static void main(String[] args) { //1. bean 和 json 互轉 Person person = new Person("xiaoli",18); String json = JsonLibUtils.bean2json(person); // {"age":18,"name":"xiaoli"} Person person2 = (Person)JsonLibUtils.json2bean(json, Person.class); //2. list 和 json 互轉 List<Person> list = new ArrayList<Person>(); list.add(new Person("李四",10)); list.add(new Person("王五",20)); String listJson = JsonLibUtils.list2json(list); // [{"age":10,"name":"李四"},{"age":20,"name":"王五"}] List json2List = JsonLibUtils.json2List(listJson); //3. map 轉 json Map<String,Person> map = new HashMap<String,Person>(); map.put("map1",new Person("李四",10)); map.put("map2",new Person("王五",20)); String mapJson = JsonLibUtils.map2json(map); // {"map2":{"age":20,"name":"王五"},"map1":{"age":10,"name":"李四"}} Map<Object, Object> map2 = JsonLibUtils.json2Map(mapJson); //4. set 與 json 互轉 Set<Person> set = new LinkedHashSet<Person>(); set.add(new Person("李四",10)); set.add(new Person("王五",20)); String setJson = JsonLibUtils.set2json(set); // [{"age":10,"name":"李四"},{"age":20,"name":"王五"}] JsonLibUtils.json2Set(setJson); } }
缺點
小結
json-lib 提供兩個對象,分別是 JSONObject
和 JSONArray
,分別對應着 JSON 的兩個數據結構。根據須要選取轉換的對象。可是因爲 json-lib 已經 n 多年沒有維護,缺陷較多,在功能和性能方面已經沒法知足咱們的需求,因此儘可能仍是不用爲好。
Gson 是 Google 公司發佈的一個開源代碼的 Java 庫,主要用途爲序列化 Java 對象爲 JSON 字符串,或反序列化 JSON 字符串爲 Java 對象。
Gson 提供了 fromJson()
和 toJson()
兩個用於解析和生成的方法,前者實現反序列化,後者實現了序列化。
依賴
使用 Gson 須要引入這個依賴。
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> <scope>compile</scope> </dependency>
Gson 工具類
封裝一些經常使用方法的轉換工具類。
public class GsonUtil { /** * bean 轉換爲 Json 字符串 */ public static String bean2json(Object object){ Gson gson = new Gson(); return gson.toJson(object); } /** * json 轉換爲 bean */ public static Object json2bean(String json,Class c){ Gson gson = new Gson(); return gson.fromJson(json,c); } /** * list 轉換爲 Json 字符串 */ public static String list2json(List list){ Gson gson = new Gson(); return gson.toJson(list); } /** * json 轉換爲 list */ public static List json2List(String json){ Gson gson = new Gson(); return gson.fromJson(json,new TypeToken<List>(){}.getType()); } /** * set 轉換爲 Json 字符串 */ public static String set2json(Set set){ Gson gson = new Gson(); return gson.toJson(set); } /** * json 轉換爲 set */ public static Set json2Set(String json){ Gson gson = new Gson(); return gson.fromJson(json,new TypeToken<Set>(){}.getType()); } /** * map 轉換爲 Json 字符串 */ public static String map2json(Map map){ Gson gson = new Gson(); return gson.toJson(map); } /** * json 轉換爲 map */ public static Map json2Map(String json){ Gson gson = new Gson(); return gson.fromJson(json,new TypeToken<Map>(){}.getType()); } }
示例代碼
public static void main(String[] args) { //1. bean 和 json 互轉 Person person = new Person("xiaoli",18); String json = GsonUtil.bean2json(person); System.out.println(json); Person person2 = (Person)GsonUtil.json2bean(json, Person.class); System.out.println(person2.toString()); //2. list 和 json 互轉 List<Person> list = new ArrayList<Person>(); list.add(new Person("李四",10)); list.add(new Person("王五",20)); String listJson = GsonUtil.list2json(list); System.out.println(listJson); List json2List = GsonUtil.json2List(listJson); System.out.println(json2List.toString()); //3. map 轉 json Map<String,Person> map = new HashMap<String,Person>(); map.put("map1",new Person("李四",10)); map.put("map2",new Person("王五",20)); String mapJson = GsonUtil.map2json(map); System.out.println(mapJson); Map<Object, Object> map2 = GsonUtil.json2Map(mapJson); System.out.println(map2.toString()); //4. set 與 json 互轉 Set<Person> set = new LinkedHashSet<Person>(); set.add(new Person("李四",10)); set.add(new Person("王五",20)); String setJson = GsonUtil.set2json(set); System.out.println(setJson); Set set1 = GsonUtil.json2Set(setJson); System.out.println(set1.toString()); } 運行結果: {"name":"xiaoli","age":18} Person(name=xiaoli, age=18) [{"name":"李四","age":10},{"name":"王五","age":20}] [{name=李四, age=10.0}, {name=王五, age=20.0}] {"map2":{"name":"王五","age":20},"map1":{"name":"李四","age":10}} {map2={name=王五, age=20.0}, map1={name=李四, age=10.0}} [{"name":"李四","age":10},{"name":"王五","age":20}] [{name=李四, age=10.0}, {name=王五, age=20.0}]
小結
Gson 是 Google 開發的,因此也是通過了不少的驗證。可是將字符串解析爲指定的集合類型須要花點時間,由於涉及到了泛型—TypeToken
。
具體的 Gson 文章詳見:Gson使用指南
Github 地址:jackson
簡單介紹一下 Jackson:
Jackson 的核心模塊由三部分組成。
ObjectMapper 經過 writeValue()
的系列方法能夠將 Java 對象序列化爲 JSON,並將 JSON 存儲成不一樣的格式。
ObjectMapper 經過 readValue()
系列方法能夠從不一樣的數據源(String、Bytes)將 JSON 反序列化爲 Java 對象。
依賴
使用 Jackson 以前,須要先添加依賴。
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.1</version> </dependency>
Jackson 工具類
public class JacksonUtil { private static ObjectMapper mapper = null; /** * bean 轉換爲 Json 字符串 */ public static String bean2json(Object object){ mapper = new ObjectMapper(); try { return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * json 轉換爲 bean */ public static Object json2bean(String json,Class c){ mapper = new ObjectMapper(); try { return mapper.readValue(json,c); } catch (IOException e) { e.printStackTrace(); } return null; } /** * list 轉換爲 Json 字符串 */ public static String list2json(List list){ mapper = new ObjectMapper(); try { return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * json 轉換爲 list */ public static List json2List(String json){ mapper = new ObjectMapper(); try { return mapper.readValue(json,List.class); } catch (IOException e) { e.printStackTrace(); } return null; } /** * set 轉換爲 Json 字符串 */ public static String set2json(Set set){ mapper = new ObjectMapper(); try { return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(set); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * json 轉換爲 set */ public static Set json2Set(String json){ mapper = new ObjectMapper(); try { return mapper.readValue(json,Set.class); } catch (IOException e) { e.printStackTrace(); } return null; } /** * map 轉換爲 Json 字符串 */ public static String map2json(Map map){ mapper = new ObjectMapper(); try { return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map); } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * json 轉換爲 map */ public static Map json2Map(String json){ mapper = new ObjectMapper(); try { return mapper.readValue(json,Map.class); } catch (IOException e) { e.printStackTrace(); } return null; } }
示例代碼
public static void main(String[] args) { //1. bean 和 json 互轉 Person person = new Person("xiaoli",18); String json = JacksonUtil.bean2json(person); System.out.println(json); Person person2 = (Person)JacksonUtil.json2bean(json, Person.class); System.out.println(person2.toString()); //2. list 和 json 互轉 List<Person> list = new ArrayList<Person>(); list.add(new Person("李四",10)); list.add(new Person("王五",20)); String listJson = JacksonUtil.list2json(list); System.out.println(listJson); List json2List = JacksonUtil.json2List(listJson); System.out.println(json2List.toString()); //3. map 轉 json Map<String,Person> map = new HashMap<String,Person>(); map.put("map1",new Person("李四",10)); map.put("map2",new Person("王五",20)); String mapJson = JacksonUtil.map2json(map); System.out.println(mapJson); Map<Object, Object> map2 = JacksonUtil.json2Map(mapJson); System.out.println(map2.toString()); //4. set 與 json 互轉 Set<Person> set = new LinkedHashSet<Person>(); set.add(new Person("李四",10)); set.add(new Person("王五",20)); String setJson = JacksonUtil.set2json(set); System.out.println(setJson); Set set1 = JacksonUtil.json2Set(setJson); System.out.println(set1.toString()); }
缺點
上面兩個缺點有待考察,若有具體例子會進行更新。
小結:
Jackson 能夠經過 ObjectMapper 的 writeValue()
和 readValue()
系列方法對 JSON 進行序列化和反序列化。而且擅長處理各類大量數據格式模塊。
具體 Jackson 文章詳見:https://www.cnblogs.com/cnjav...
FastJson 是由阿里巴巴開源的 JSON 解析庫,它能夠進行快速的序列化和反序列化。功能仍是很強大的。使用 fastjson 須要注意,轉換的類必須有默認的無參構造函數。
Github:fastjson
fastjson 對於 JSON 字符串解析主要用到了下面三個類:
toJSONString
和 parseObject
方法對 JSON 進行序列化和反序列化。依賴
使用 fastjson 前,須要引入相關依賴。
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.61</version> </dependency>
fastjson 工具類
public class FastJsonUtil{ /** * bean 轉換爲 Json 字符串 */ public static String bean2json(Object object){ return JSON.toJSONString(object); } /** * json 轉換爲 bean */ public static Object json2bean(String json,Class c){ return JSON.parseObject(json,c); } /** * list 轉換爲 Json 字符串 */ public static String list2json(List list){ return JSON.toJSONString(list); } /** * json 轉換爲 list */ public static List json2List(String json,Class c){ return JSON.parseArray(json,c); } /** * set 轉換爲 Json 字符串 */ public static String set2json(Set set){ return JSON.toJSONString(set); } /** * json 轉換爲 set */ public static Set json2Set(String json){ return JSON.parseObject(json,Set.class); } /** * map 轉換爲 Json 字符串 */ public static String map2json(Map map){ return JSON.toJSONString(map); } /** * json 轉換爲 map */ public static Map json2Map(String json){ return JSON.parseObject(json); } }
實例代碼
public class FastJsonTest { public static void main(String[] args) { //1. bean 和 json 互轉 Person person = new Person("xiaoli",18); String json = FastJsonUtil.bean2json(person); System.out.println(json); Person person2 = (Person)FastJsonUtil.json2bean(json, Person.class); System.out.println(person2.toString()); //2. list 和 json 互轉 List<Person> list = new ArrayList<Person>(); list.add(new Person("李四",10)); list.add(new Person("王五",20)); String listJson = FastJsonUtil.list2json(list); System.out.println(listJson); List json2List = FastJsonUtil.json2List(listJson, Person.class); System.out.println(json2List.toString()); //3. map 轉 json Map<String,Person> map = new HashMap<String,Person>(); map.put("map1",new Person("李四",10)); map.put("map2",new Person("王五",20)); String mapJson = FastJsonUtil.map2json(map); System.out.println(mapJson); Map<Object, Object> map2 = FastJsonUtil.json2Map(mapJson); System.out.println(map2.toString()); //4. set 與 json 互轉 Set<Person> set = new LinkedHashSet<Person>(); set.add(new Person("李四",10)); set.add(new Person("王五",20)); String setJson = FastJsonUtil.set2json(set); System.out.println(setJson); Set set1 = FastJsonUtil.json2Set(setJson); System.out.println(set1.toString()); } } 運行結果: {"age":18,"name":"xiaoli"} Person(name=xiaoli, age=18) [{"age":10,"name":"李四"},{"age":20,"name":"王五"}] [Person(name=李四, age=10), Person(name=王五, age=20)] {"map2":{"age":20,"name":"王五"},"map1":{"age":10,"name":"李四"}} {"map2":{"name":"王五","age":20},"map1":{"name":"李四","age":10}} [{"age":10,"name":"李四"},{"age":20,"name":"王五"}] [{"name":"王五","age":20}, {"name":"李四","age":10}]
小結
fastjson 雖然很快,我仍是挺推薦使用的,但仍是有些缺點的。具體詳見:fastjson這麼快老外爲啥仍是熱衷 jackson?
咱們對本篇文章作個總結:
什麼是 JSON:數據交互語言,獨立於任何程序語言的文本格式。
爲何使用 JSON:javaScript 原生支持 JSON,解析速度更快;比 xml 更易使用。
如何使用 JSON:
parse()
和 stringift()
實現 json 的反序列化和序列化。對此,咱們瞭解了 JSON,而且會對 JSON 進行序列化和反序列化。