蓝旭暑期培训Day3——JSON使用与简单解析
Posted 嗯我想想
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝旭暑期培训Day3——JSON使用与简单解析相关的知识,希望对你有一定的参考价值。
蓝旭暑期培训Day3——JSON使用与解析
JSON是什么
JSON(javascript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。摘自百度百科
- JSON是一种轻量级(Light-Meight)、基于文本的(Text-Based)、可读的(Human-Readable)格式。
- JSON 的名称中虽然带有JavaScript,但这是指其语法规则是参考JavaScript对象的,而不是指只能用于JavaScript 语言。
- 因为JSON本身就是参考JavaScript 对象的规则定义的,其语法与JavaScript定义对象的语法几乎完全相同。
- JSON格式的创始人声称此格式永远不升级,这就表示这种格式具有长时间的稳定性,10 年前写的文件,10年后也能用,没有任何兼容性问题。
JSON的语法规则
JSON的语法规则比较简单,上面也说过与JavaScript的语法相类似,大概有以下几点:
- 数组 (Array) 用方括号
[]
表示。 - 对象 (Object) 用大括号
{}
表示。 - 存值方式:键值对 key-value 可以组合成数组和对象。
- key 需要放在置于双引号中,value需要分情况。
- 值(value)有字符串、数值、布尔值、null、对象和数组。
- 并列的数据之间用英文逗号
,
进行分割隔。
下面看一个JSON字符串的例子
{
"username":"wubh576",
"password":"HelloBluemsun",
"age":21,
"girlfriend":null,
"isStudent":true,
"selectedCourses":[
"高等数学A-1","Java","信息安全"
],
"coursesGrade":[60,60,60],
"hisPet":{
"name":"Chris",
"variety":"英短银渐层",
"favoriteFoods":["小鱼干","鸡胸肉","酸奶"]
},
"data":{
"studentNum":2,
"detail": [{
"id": 1,
"name": "贺嘉",
"age": "19"
},{
"id": 2,
"name": "谭斯艺",
"age": "19"
}
]
},
"status":"success"
}
JSON实际应用
为什么说是简单解析呢?
在交互中,后端同学承担的任务是对前端发来的JSON字符串进行解析,而这个字符串的格式你们可以预先通过接口文档确定好的,它不是一个未知的字符串,而是具有一定格式的,所以不会涉及用for加强循环去解析未知的JSON字符串。
前端同学需要掌握:JSON的解析和生成(JavaScript实现)、JSON 和 JavaScript 的互转
后端同学需要掌握:JSON的解析和生成(Java实现)、JSON 和 Java 对象的互转
需要注意的是,之前后端同学 view层的 jsp 与controller层的 servlet 进行交互是通过form表单的形式,而之后暑期的项目前后端数据是通过JSON字符串进行交互的
。
GSON——JSON的序列化与反序列化
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。
也就是个jar包,maven的Gson下载传送门!讲课用的版本是2.8.6
- fromJson() 反序列化
Gson提供了fromJson()方法来实现从JSON字符串到Java实体的方法。(此处看一下源码)
先来个JSON字符串的解析栗子🌰
package jsondemo;
import com.google.gson.Gson;
import entity.User;
public class JsonToObjectDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
Gson gson = new Gson();
String jsonString = "{\\"userId\\":1,\\"username\\":\\"wubh576\\",\\"password\\":\\"HelloBluemsun\\",\\"grade\\":\\"2019\\"}";
System.out.println(jsonString);
User user = gson.fromJson(jsonString,User.class);
System.out.println(user);
}
}
再来看个栗子🌰
package jsondemo;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import entity.Bluemsun;
import entity.User;
import java.lang.reflect.Type;
import java.util.List;
public class JsonToListDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
String jsonString = "[\\n" +
" {\\n" +
" \\"username\\": \\"tom\\",\\n" +
" \\"password\\": \\"123456\\"\\n" +
" },\\n" +
" {\\n" +
" \\"username\\": \\"tony\\",\\n" +
" \\"password\\": \\"1234567\\"\\n" +
" }\\n" +
"]";
Gson gson = new Gson();
Type type = new TypeToken<List<User>>(){}.getType(); // Type是Java语言中所有类型的公共父接口,在Java泛型与反射中作用比较大,现在仅会用就行
List<User> userList = gson.fromJson(jsonString,type);
System.out.println(userList);
Type type_1 = new TypeToken<List<Bluemsun>>(){}.getType();
List<Bluemsun> bluemsunList = gson.fromJson(jsonString,type_1);
System.out.println(bluemsunList); // 注意:变量名跟JSON数据字段名必须一致,否则无法将JSON字符串反序列化
}
}
其他解析情况,根据上述两种情况进行相对应的代码修改即可。
- toJson() 序列化
栗子🌰将user对象进行序列化为JSON字符串
package jsondemo;
import com.google.gson.Gson;
import entity.User;
public class ObjectToJsonDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
Gson gson = new Gson();
User user = new User();
user.setUsername("wubh");
user.setPassword("123456");
String jsonString = gson.toJson(user);
System.out.println(jsonString);
}
}
栗子🌰序列化对象数组为JSON字符串
package jsondemo;
import com.google.gson.Gson;
import entity.User;
import java.util.ArrayList;
import java.util.List;
public class ListToJsonDemo {
//这是一个main方法,是程序的入口
public static void main(String[] args) {
User user = new User();
User user1 = new User();
user.setUsername("hej");
user.setPassword("123456");
user1.setUsername("wubh");
user1.setPassword("123456");
List<User> userList = new ArrayList<>();
userList.add(user);
userList.add(user1);
Gson gson = new Gson();
String jsonString = gson.toJson(userList);
System.out.println(jsonString);
}
}
到这里呢,咱们已经掌握了通过GSON去进行JSON的序列化及反序列化,大家可以自己写JSON字符串和代码去尝试进行序列化和反序列化。
下面我们就模拟前后端交互来具体的看一下如何使用JSON。
前后端交互JSON实操
先来聊聊如何获取前端传来的JSON字符串
首先我们来看一下前端post请求的ajax的代码(当然只用看就行了,不用会写,咱们是后端!)
<script>
function send() {
// 创建对象
var xhr = new XMLHttpRequest();
// 设置基本信息
xhr.open('post', 'http://localhost:8886/');
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
//设置监听
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log("success");
if (xhr.responseText) {
console.log(JSON.parse(xhr.responseText)); //接收后端传过来的数据
} else {
console.log(xhr.responseXML); //接收后端传来的XML格式的数据
}
}
}
// 发送信息
xhr.send(JSON.stringify({
studentnum: document.getElementById("studentnum").value,
password: document.getElementById("psw").value,
}));
}
</script>
这段代码是昨天谭然学姐讲课的时候用到的代码,我们来看几个关键的地方。
设置请求头 Content-Type
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');
Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些 php 网页点击的结果却是下载一个文件或一张图片的原因。
Content-Type 标头告诉客户端实际返回的内容的内容类型。
Content-Type 分类
我们要用到的就是:
Content-Type: application/json
它作为响应头比较常见,用来告诉服务端消息主体是序列化后的 JSON 字符串,其中一个好处就是JSON 格式支持比键值对复杂得多的结构化数据。由于 JSON 规范的流行,除了低版本 IE 之外(不要再用IE了)的各大浏览器都原生支持JSON.stringify,服务端语言也都有处理 JSON 的函数,使用非常方便。
如果想有更多了解,请参考菜鸟教程HTTP Content-Type
所以后台接受过来的应该是在request中传过来的JSON数据文件,那么提到文件,就可以联想到我们之前讲过的JavaIO了。我们需要利用JavaIO进行JSON数据文件的读取,进而获得正确的JSON字符串,上代码。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取前端发来的数据,并进行处理
StringBuilder stringBuilder = null;
String jsonString = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()));
stringBuilder = new StringBuilder();
String str = "";
while ((str = bufferedReader.readLine()) != null) {
stringBuilder.append(str);
}
// 获取处理好的json字符串
jsonString = stringBuilder.toString();
// 利用GSON进行JSON字符串的反序列化
Gson gson = new Gson();
User user = gson.fromJson(jsonString, User.class);
user.setUsername(user.getUsername());
user.setPassword(user.getPassword());
System.out.println(user);
}
其实原理很简单:就是读入了request请求中的JSON数据文件,然后将其变为字符串就好了。
现在已经能获取到了前端发送过来JSON字符串了,结合前面学过的GSON再将JSON字符串反序列化为Java对象,之后就随你操作啦~
下面我们来看看如何给前端返回JSON数据呢?
之前已经提过了JSON的存值方式是key-value形式的,所以你要去自己封装一个对象并序列化为JSON字符串传给前端。这里,我用到的是之前讲过Java容器中的Map,为什么,因为Map的存值方式也是key-value形式,但是其他的容器类也是可以根据情况进行使用的。
例如,我们想给前端传输这样一个格式的JSON字符串
{
"msg": "Login success!",
"data": {
"username": "wubh2",
"password": "123456"
},
"status": 1
}
根据刚才的思路,继续上代码。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Gson gson = new Gson();
User user1 = new User();
user1.setUsername("wubh2");
user1.setPassword("123456");
Map map = new HashMap();
map.put("msg","Login success!");
map.put("status",1);
map.put("data",user1);
// 先将map处理好后,再调用response.getWriter()
// 使用JSON将返回数据返回给前端
PrintWriter out = response.getWriter();
/**
* 但是为什么用response呢?而不是new一个PrintWriter对象呢?
* 返回响应给客户端 你如果想自己实现一遍response的功能当然也OK
* response限制在当前http请求中,与request相呼应。
*/
String jsonStr = gson.toJson(map); // 自动写入,不必再调用out.write()方法,否则会重复。
out.println(jsonStr);
// out用完后需要 flush 一下,清空一下缓冲区
out.flush();
}
到现在JSON的使用与简单解析就差不多已经讲完了,这块呢是交互的重点部分,因为涉及到数据的交互,如果前后端连数据都交互不正确的话,那这这这就没法交互成功了,所以前端要搞懂ajax,后端也需要稍有了解,对于JSON则是都要比较清楚明白。
本次JSON暂时不布置作业了,前后端队友可以花点时间交流一下对于ajax以及JSON的理解。
以上是关于蓝旭暑期培训Day3——JSON使用与简单解析的主要内容,如果未能解决你的问题,请参考以下文章