最近搬砖感严重。好不容易遇到不会的地方,反而又急躁想敷衍了事。现在想想只有不会的地方才能学到东西,这才是最应该值得期待的地方。如此想来真的是为了完成项目而本末倒置了,在做项目中学到知识,巩固知识,这才是做项目的本,完成项目,赚到一点钱,完成老板给的任务,这才是末。
想搞懂网络请求,必须搞懂这样几个关键词。
0.什么是流,什么是文件流
https://blog.youkuaiyun.com/hguisu/article/details/7418161?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166531113616782427467778%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166531113616782427467778&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~hot_rank-2-7418161-null-null.142v52control,201v3control_2&utm_term=%E4%BB%80%E4%B9%88%E6%98%AF%E6%B5%81&spm=1018.2226.3001.4187
参考这篇文章
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。
总结的基本概念如下:
-
数据流:
一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。
-
输入流(Input Stream):
程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道
-
输出流:
程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。
采用数据流的目的就是使得输出输入独立于设备。
Input Stream不关心数据源来自何种设备(键盘,文件,网络)
Output Stream不关心数据的目的是何种设备(键盘,文件,网络)
- 数据流分类:
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
-
字节流:数据流中最小的数据单元是字节
-
字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
字节流可以处理一切文件,而字符流只能处理纯文本文件。
1.可传输的文件流
2.序列化和反序列化
2.1可序列化的java对象
什么是序列化和反序列化?
序列化:把Java对象转换为字节序列的过程。
反序列化:把字节序列恢复为Java对象的过程。
之所以需要序列化和反序列化,主要是因为Java对象是在JVM中生成的,是内存中的数据,如果需要把对象的字节序列远程传输或保存到硬盘上时,你就需要将Java对象转换成二进制流。 这个转换过程就是序列化。
序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中。
假如别人传给你一个二进制流数据,当你想要恢复成内存中的对象时,你就需要反序列化
序列化操作可读:
https://lixuekai.blog.youkuaiyun.com/article/details/78544505
https://blog.youkuaiyun.com/tree_ifconfig/article/details/82766587
以我们使用HttpURLCon 工具在安卓中进行网络请求为例,可以看到我们设置请求体参数时候设置的是可序列化的java对象
市面上的几种序列化方式
Java对象是在JVM中生成的,如果需要远程传输或保存到硬盘上,就需要将Java对象转换成可传输的文件流。
市面上目前有的几种转换方式:
- 利用Java的序列化功能序列成字节(字节流)也就是接下来要讲的。一般是需要加密传输时才用。
- 将对象包装成JSON字符串(字符流)
转Json工具有Jackson、FastJson或者GJson,它们各有优缺点:
JackSon:Map、List的转换可能会出现问题。转复杂类型的Bean时,转换的Json格式不是标准的Json格式。适合处理 大文本Json。
FastJosn:速度最快。将复杂类型的Bean转换成Json可能会有问题:引用类型如果没有引用被出错。适合对性能有要求的场景。
GJson:功能最全,可以将复杂的Bean和Json字符串进行互转。性能上面比FastJson有所差距。适合处理小文本Json,和对于数据正确性有要求的场景。 - protoBuf工具(二进制)
性能好,效率高,字节数很小,网络传输节省IO。但二进制格式可读性差。
具体用法,与json的格式,可见这篇文章:
https://blog.youkuaiyun.com/leosblog/article/details/80842640?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166531525616800182140364%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166531525616800182140364&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~hot_rank-2-80842640-null-null.142v52control,201v3control_2&utm_term=java%20json&spm=1018.2226.3001.4187
总的来说:
我们要网络请求,就得把数据序列化成字节流或者字符流
而把对象变成json,就是说是把对象 变成符合json格式的字符串
这里用js 举例子,其实也能方便我们理解
我们所说的json序列化 就是说 把对象转化成json格式的字符串而已
这个字符串是不是就是字节流,,应该差不多吧
3.json/xml以及其数据传递
json/xml的数据传递:
在数据传输(也可称为网络传输)前,先通过序列化工具类将Java对象序列化为json/xml文件。
在数据传输(也可称为网络传输)后,再将json/xml文件反序列化为对应语言的对象
JSON 是文本格式,能用于在不同编程语言中交换结构化数据。
而「字符串」是大部分编程语言中存储文本数据的数据类型,在这些编程语言中你可以把 JSON (文本)存储在字符串内。
(1)利用传统方式:
由实体类生成Json字符串:
public Person getPerson(){
return new Person("张三", "男", 25);
}
@Test
public void EntityToJson(){
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", getPerson().getName());
jsonObject.put("sex", getPerson().getSex());
jsonObject.put("age", getPerson().getAge());
System.out.println(jsonObject.toString());
}
由Json字符串生成实体类:
@Test
public void JsonToEntity(){
String jsonString = "{\"sex\":\"男\",\"name\":\"张三\",\"age\":25}";
JSONObject jsonObject = new JSONObject(jsonString);
Person person = new Person(jsonObject.get("name").toString(), jsonObject.get("sex").toString(), Integer.valueOf(jsonObject.get("age").toString()));
System.out.println(person.toString());
}
(一)、简单值的形式:JSON的简单值的格式对应着JS中的基础数据类型:数字 字符串 布尔值
(二)、对象形式:对应着JS中的对象,由花括号括起来
(三)、json数组形式,由方括号括起来
JSONArray dataArray=json_str.getJSONObject(“data”).getJSONArray(“items”);
json数组和List之间的转换
//list对象数组 转换为 json字符串
String imagesExamineJson = JSON.toJSONString(caseModularList);
//将数据库中的json字符串转换为 List对象
List<CaseModular> caseModularList = JSON.parseObject(this.imagesExamineJson, new TypeReference<List<CaseModular>>() {});