前言: 最近也是期末了,有好多好多文档和实验报告要交,所以都没啥时间写文,这段时间清闲了,来补一下之前学习时遗漏的一些知识树,话说就没人吐槽这个JSON图标好丑吗?
*
JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。
这里有意思的是,JSON本来是用来表示 JavaScript 对象的一种数据文本格式,但由于它轻量级、易于解析/操作(JavaScript原生支持)的一些特点,渐渐的被很多语言支持也就成了一种标准
在JSON之前,我们通常在网络传输中使用的格式是XML,在我们的印象之中,XML具有很好的可读性,并且格式统一,解析起来也相对比较简单,为什么摒弃掉XML而逐渐的使用起JSON呢?
主要原因在于:JSON比XML更小、更快、更易解析。
接下来我们通过一个实例的比较来真实的说明一下XML与JSON的区别:
XML
表示中国部分省市的数据如下:<?xml version="1.0" encoding="utf-8" ?> <country> <name>中国</name> <province> <name>黑龙江</name> <citys> <city>哈尔滨</city> <city>大庆</city> </citys> </province> <province> <name>广东</name> <citys> <city>广州</city> <city>深圳</city> <city>珠海</city> </citys> </province> <province> <name>台湾</name> <citys> <city>台北</city> <city>高雄</city> </citys> </province> <province> <name>新疆</name> <citys> <city>乌鲁木齐</city> </citys> </province> </country>
JSON
中国部分省市数据如下:var country = { name: "中国", provinces: [ { name: "黑龙江", citys: { city: ["哈尔滨", "大庆"]} }, { name: "广东", citys: { city: ["广州", "深圳", "珠海"]} }, { name: "台湾", citys: { city: ["台北", "高雄"]} }, { name: "新疆", citys: { city: ["乌鲁木齐"]} } ] }
从编码的可读性来说,XML
有明显的优势,毕竟人类的语言更贴近这样的说明结构。而JSON
读起来更像是一个数据块,读起来比较费解,不过我们读起来费解的语言,恰恰是适合机器于都的,所以通过JSON
是的索引contry.provinces[0].name
就可以读取到“黑龙江”这个值
从编码的手写难度来说,XML
还是更简单一些,好读也就意味着好写;不过JSON
写出来的字符明显就少很多;去掉空白制表以及换行的话,JSON
就是密密麻麻的有用数据,而XML
却包含很多重复的标记字符。
使用XML:
使用JSON:
客户端与服务器交换的数据无非就是两种: 数组或者是对象,JSON所表示的数据也就是这两种了
JSON语法是JavaScript语法的子集,在JavaScript中用[]
中括号来表示数组,用{}
大括号来表示对象,JSON也是这样
[]
中括号里面的内容有些像ArrayList,是一个列表一样的东西
var employees = [ { "firstName":"Bill" , "lastName":"Gates" }, { "firstName":"George" , "lastName":"Bush" }, { "firstName":"Thomas" , "lastName": "Carter" } ];
{}
大括号里面的东西有些像Map,是一对一对的键值对
var obj = { age:20, str:"wmyskxz", method:function() { alert("我爱学习"); } };
[]
中括号和{}
大括号之间是可以相互嵌套的在解析JSON对象之前,我们需要首先地来创造一个JSON对象:
<script> var JASONObject = {"name": "我没有三颗心脏", "age": 21}; </script>
在HTML中我们可以直接使用.
点号来直接访问JSON对象的属性:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JSON学习</title> </head> <body> <p> Name:<span id="name"></span><br> Age:<span id="age"></span><br> </p> <script> var JASONObject = {"name": "我没有三颗心脏", "age": 21}; document.getElementById("name").innerHTML = JASONObject.name; document.getElementById("age").innerHTML = JASONObject.age; </script> </body> </html>
打开网页我们能正确看到如下效果:
但通常情况中,我们拿到和上传的并不是一个真正的JSON对象,而是一串由JSON转换得来的字符串,我们同样在HTML中模拟解析一下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JSON学习</title> </head> <body> <p> Name:<span id="name"></span><br> Age:<span id="age"></span><br> </p> <script> var txt = '{"students":[' + '{"name":"我没有三颗心脏0","age":21},' + '{"name":"我没有三颗心脏1","age":21 }]}'; var obj = eval("(" + txt + ")"); document.getElementById("name").innerHTML = obj.students[1].name; document.getElementById("age").innerHTML = obj.students[1].age; </script> </body> </html>
打开网页即可看到如下正确效果:
我们这里演示使用AJAX请求的方式来提交JSON数据到后台:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JSON学习</title> <!-- 因为不想手动引感觉挺麻烦,引了个菜鸟教程的 --> <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script> </head> <body> <form> id:<input type="text" id="id" value="123"/><br/> 名称:<input type="text" id="name" value="category xxx"/><br/> <input type="button" value="提交" id="sender"> </form> <div id="messageDiv"></div> <script> $('#sender').click(function () { var id = document.getElementById('id').value; var name = document.getElementById('name').value; var category = {"name": name, "id": id}; var jsonData = JSON.stringify(category); var page = "category"; $.ajax({ type: "put", url: page, data: jsonData, dataType: "json", contentType: "application/json;charset=UTF-8", success: function (result) { } }); alert("提交成功,请在springboot控制台查看服务端接收到的数据"); }); </script> </body> </html>
JSON.stringify()
来将一个JSON对象转换成了一串字符串,并且在AJAX中,我们设置了 dataType
和 contentType
来告知后台我们传输的是一个JSON数据简单写一个Controller来验证一下吧:
@PutMapping("/category") public void addCategory(@RequestBody Category category) throws Exception { System.out.println("springboot接受到浏览器以JSON格式提交的数据:" + category.getId() + category.getName()); } -----------控制台打印信息:---------- springboot接受到浏览器以JSON格式提交的数据:123 category xxx
引用自:
在后台有许多支持解析JSON的库,目前对于Java开源的JSON类库有许多,下面我们介绍三种比较常用的JSON库,并进行比对说明,它们分别是:
Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。而且Jackson社区相对比较活跃,更新速度也比较快。Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式。
我看了一些资料,比较印象深刻的是:FastJson在复杂类型的Bean转换Json上会出现一些问题,但是在解析JSON时却是最快的(具体参考:知乎:fastjson这么快老外为啥还是热衷 jackson?)
总结如下:
为了导库简单,我在这里都使用Maven搭建的SpringBoot项目来演示,Maven库的地址在这里:https://mvnrepository.com/
在使用之前,我们先来建设一些基础类,用于支持JSON库的使用:
public class Person { private String name; private Integer age; /* getter and setter */ @Override public String toString() { return "名字为" + name + ",年龄" + age; } }
(1)Maven依赖:
<!-- Gson库 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency>
(2)使用示例:
@Test public void tester() { Gson gson = new Gson(); /* —————————————————— 准备测试数据 —————————————————— */ Person person1 = new Person(); person1.setName("我没有三颗心脏1"); person1.setAge(21); Person person2 = new Person(); person2.setName("我没有三颗心脏2"); person2.setAge(21); Person person3 = new Person(); person3.setName("我没有三颗心脏3"); person3.setAge(21); List<Person> list = new ArrayList<>(); list.add(person1); list.add(person2); list.add(person3); /* —————————————————— 简单的Bean转为JSON —————————————————— */ String jsonString = gson.toJson(person1); System.out.println("简单的Bean转为JSON:" + jsonString); /* —————————————————— JSON转为简单Bean —————————————————— */ Person personFromJson = gson.fromJson(jsonString, Person.class); System.out.println("JSON转为简单Bean:" + personFromJson.toString()); /* —————————————————— 带泛型的List转JSON —————————————————— */ String jsonStringFromList = gson.toJson(list); System.out.println("带泛型的List转JSON:" + jsonStringFromList); /* —————————————————— JSONz转为带泛型的List —————————————————— */ List<Person> retList = gson.fromJson(jsonStringFromList, new TypeToken<List<Person>>() { }.getType()); for (Person tempPerson : retList) { System.out.println(tempPerson.toString()); } } ------------------结果如下------------------ 简单的Bean转为JSON:{"name":"我没有三颗心脏1","age":21} JSON转为简单Bean:名字为我没有三颗心脏1,年龄21 带泛型的List转JSON:[{"name":"我没有三颗心脏1","age":21},{"name":"我没有三颗心脏2","age":21},{"name":"我没有三颗心脏3","age":21}] 名字为我没有三颗心脏1,年龄21 名字为我没有三颗心脏2,年龄21 名字为我没有三颗心脏3,年龄21
好文推荐及扩展阅读:你真的会用Gson吗?Gson使用指南(一)
(1)Maven依赖:
<!-- FastJson库 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
(2)使用示例:
@Test public void tester() { /* —————————————————— 准备测试数据 —————————————————— */ Person person1 = new Person(); person1.setName("我没有三颗心脏1"); person1.setAge(21); Person person2 = new Person(); person2.setName("我没有三颗心脏2"); person2.setAge(21); Person person3 = new Person(); person3.setName("我没有三颗心脏3"); person3.setAge(21); List<Person> list = new ArrayList<>(); list.add(person1); list.add(person2); list.add(person3); /* —————————————————— 简单的Bean转为JSON —————————————————— */ String jsonString = JSON.toJSONString(person1); System.out.println("简单的Bean转为JSON:" + jsonString); /* —————————————————— JSON转为简单Bean —————————————————— */ Person personFromJson = JSON.parseObject(jsonString, Person.class); System.out.println("JSON转为简单Bean:" + personFromJson.toString()); /* —————————————————— 带泛型的List转JSON —————————————————— */ String jsonStringFromList = JSON.toJSONString(list); System.out.println("带泛型的List转JSON:" + jsonStringFromList); /* —————————————————— JSONz转为带泛型的List —————————————————— */ List<Person> retList = JSON.parseObject(jsonStringFromList, new TypeReference<List<Person>>() { }); for (Person tempPerson : retList) { System.out.println(tempPerson.toString()); } } ------------------结果如下------------------ 简单的Bean转为JSON:{"age":21,"name":"我没有三颗心脏1"} JSON转为简单Bean:名字为我没有三颗心脏1,年龄21 带泛型的List转JSON:[{"age":21,"name":"我没有三颗心脏1"},{"age":21,"name":"我没有三颗心脏2"},{"age":21,"name":"我没有三颗心脏3"}] 名字为我没有三颗心脏1,年龄21 名字为我没有三颗心脏2,年龄21 名字为我没有三颗心脏3,年龄21
官方文档:戳这里,据官方说法,FastJson比Gson要快上6倍哦!
(1)Maven依赖:
稍微麻烦一点的是Jackson需要依赖三个包
<!-- jackson库 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.5</version> </dependency>
(2)使用示例:
@Test public void tester() throws IOException { /* —————————————————— 准备测试数据 —————————————————— */ Person person1 = new Person(); person1.setName("我没有三颗心脏1"); person1.setAge(21); Person person2 = new Person(); person2.setName("我没有三颗心脏2"); person2.setAge(21); Person person3 = new Person(); person3.setName("我没有三颗心脏3"); person3.setAge(21); List<Person> list = new ArrayList<>(); list.add(person1); list.add(person2); list.add(person3); /* ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现的 */ ObjectMapper mapper = new ObjectMapper(); /* —————————————————— 简单的Bean转为JSON —————————————————— */ String jsonString = mapper.writeValueAsString(person1); System.out.println("简单的Bean转为JSON:" + jsonString); /* —————————————————— JSON转为简单Bean —————————————————— */ Person personFromJson = mapper.readValue(jsonString, Person.class); System.out.println("JSON转为简单Bean:" + personFromJson.toString()); /* —————————————————— 带泛型的List转JSON —————————————————— */ String jsonStringFromList = mapper.writeValueAsString(list); System.out.println("带泛型的List转JSON:" + jsonStringFromList); /* —————————————————— JSONz转为带泛型的List —————————————————— */ // List<LinkedHashMap<String, Person>> retList = mapper.readValue(jsonStringFromList, List.class); // for (int i = 0; i < retList.size(); i++) { // Map<String, Person> map = retList.get(i); // Set<String> set = map.keySet(); // for (Iterator<String> it = set.iterator(); it.hasNext();) { // String key = it.next(); // System.out.println(key + ":" + map.get(key)); // } // } /* —————————————————— JSONz转为Array数组 —————————————————— */ Person[] retList = mapper.readValue(jsonStringFromList, Person[].class); for (int i = 0; i < retList.length; i++) { System.out.println(retList[i].toString()); } } ------------------结果如下------------------ 简单的Bean转为JSON:{"name":"我没有三颗心脏1","age":21} JSON转为简单Bean:名字为我没有三颗心脏1,年龄21 带泛型的List转JSON:[{"name":"我没有三颗心脏1","age":21},{"name":"我没有三颗心脏2","age":21},{"name":"我没有三颗心脏3","age":21}] 名字为我没有三颗心脏1,年龄21 名字为我没有三颗心脏2,年龄21 名字为我没有三颗心脏3,年龄21
SpingMVC和SpringBoot一样,都能通过注解的方式获取并返回一串JSON格式的数据,我们使用SpringBoot的一段实例程序来实际说明一下:
@RequestMapping("/jsonCategory") @ResponseBody // 该注解表示我们的请求不再交给springmvc处理,而是结合JSON包,将对象解析成JSON字符串 public Category jsonCategory() { return new Category(123, "我没有三颗心脏"); }
我们在浏览器中访问地址:localhost:8080/jsonCategory
,会得到以下JSON数据:
我们也可以使用 @RequestBody
来获取一串JSON数据:
@PutMapping("/category") public void addCategory(@RequestBody Category category) { System.out.println("springboot接受到浏览器以JSON格式提交的数据:" + category.getId() + category.getName()); }
我们在前台使用的是上面用过的用于提交JSON数据的页面,运行能够成功得到结果:
@RestController
注解,是@ResponseBody和@Controller的组合注解,用于返回JSON数据。欢迎转载,转载请注明出处!
简书ID:@我没有三颗心脏
github:wmyskxz
欢迎关注公众微信号:wmyskxz_javaweb
分享自己的Java Web学习之路以及各种Java学习资料
如对本文有疑问, 点击进行留言回复!!
NullPointerException: Attempt to invoke virtual method ‘android.content.res.XmlResourceParser androi
关于启动appium-desktop,报错:Cannot extract apk info using apkanalyzer. Falling back to aapt. Original ....
Gradle 发布共享库——如何通过Gradle发布Android依赖库(aar)到 jitpack 公共仓库
Gradle 发布共享库——如何通过Gradle发布java依赖库(jar)到 jitpack 公共仓库(—)
网友评论