公众号:小李不秃,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 进行序列化和反序列化。