新Java网络编程(更新中)
目录
一、HTTP协议原理
1.协议
2.HTTP/HTTPS协议
3.URL(Uniform Resource Locator统一资源定位符)
4.相对路径和默认路径
二.简单的API调用
1.如何使用Java实现抓取网站内容
2.什么是API
定义
小结
案例
3.POST表单数据
三.Request Response对象
1.Response-网页
2.Response-非文本文件
3.Response-JSON
4.解析JSON对象
四.Headers
1.User-Agent
HTTP header
User-Agent
2.Referer
防盗链
为什么直接贴网址可以访问?
程序中的Referer
3.Host
五.下载文件、图片
1.下载文件
写入文本文件
写入二进制文件
2.下载图片
3.解析Excel
调用库
六.cookie & session
1.cookie
2.session
一、HTTP协议原理
1.协议
什么是协议,网络协议的简称,网络协议是通信计算机双方必须遵从的一组约定,例如如何建立连接,怎么样互相识别文档。只有遵守了这个约定,计算机之间才能相互通信交流。
2.HTTP/HTTPS协议
HTTP | HTTPS | |
端口 | 80 | 443 |
数据传输 | 明文传输 | 加密传输 |
真假网站识别 | 易被复制 | 有证书,难被复制 |
浏览器显示区别 | 浏览器显示问号,提示不安全 | 浏览器显示小锁,提示安全 |
门槛 | 无需证书 | 需要Gworg机构颁发证书,需要一定的成本 |
安全性 | 容易被劫持,跳转到其他网站 | 加密安全,很难被劫持,交易数据加密 |
如果大家对于两种协议感兴趣,可以查看这个这个文档
3.URL(Uniform Resource Locator统一资源定位符)
协议类型与域名之间以://分隔
路径以/开头,中间每层的分割也是/,路径相当于一层层的文件夹
路径和参数之间用?分隔,多个单数之间用&分割,参数用"参数名=参数值"的格式来表示
4.相对路径和默认路径
1.相对路径
gallery/topic/116390/?from=hot_topic_note&sort=new
注意,不是以斜杠/开头的路径,表示相对路径,如上面所示,这种相对路径非常容易出错
2.默认路径
我们在上网的时候,仅仅输入了https://www.douban.com或者https://www.douban.com都能打开豆瓣首页,并没有输入路径。实际上,没有输入路径,表示请求网站的默认页面,那么服务器就会返回一个默认的页面给浏览器,而默认页面是什么页面,是由服务器来决定,通常服务器默认的页面是首页。
二.简单的API调用
1.如何使用Java实现抓取网站内容
安装依赖库
首先安装一个Okhttp3,这是一个非常流行的HTTP库,可以简单快速的实现HTTP调用
安装Okhttp3的方式是在pom.xml文件中添加依赖:
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.1.0</version>
</dependency>
示例爬取网站内容
package com.web.get;import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;import java.io.IOException;public class GetPage {public String getContent(String url){OkHttpClient okHttpClient = new OkHttpClient();//定义一个请求配置urlRequest request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);String result = null;try {result = call.execute().body().string();} catch (Exception e) {e.printStackTrace();}//返回结果return result;}
}
2.什么是API
API (应用程序编程接口)
我们经常听到 API
这个专业名称。那么什么是 API
呢?
定义
API
(Application Programming Interface,应用程序接口)是一些预先定义的函数,或指软件系统不同组成部分衔接的约定。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问原码,或理解内部工作机制的细节。
在互联网时代,API
常常以 URL
的形式提供给开发者。URL
的 路径(英文称作path
)部分就是函数,而函数的参数就等同于 URL
的参数(英文称作paramter
或简称param
)。
下图是 URL
格式参考图:
小结
我们常说的 API
有两种:
调用别的代码接口;
调用一个
URL
(需要发HTTP
请求)。
这两种都是 API
,在网络编程的场景下,API
经常指的是第二种。无论哪一种,简言之,都是触发一个功能,取得相应的结果。
案例
对于第二种,调用一个 URL
形式的 API
,最常见的场景是需要取得数据,API
把数据以某种格式进行包装后返回给调用者。
例如,我们常常在网站上看到天气信息
网站上调用天气的数据 API
(会在 URL
参数中指定城市),取得天气数据后,显示在网站上。网站不需要知道天气数据是如何获取的(涉及到复杂的气象观测、气象数据运算),拿到数据后,可以灵活把天气信息显示在任意的位置,这是由网站自己决定的。
由此可见,API
只是提供纯粹的数据(7゜c),并不包含与展示相关的字体颜色、字体大小、位置等信息。而网站作为调用者,只需要关心如何展示更漂亮,而不需要关心具体的数据。
3.POST表单数据
Okhttp3库也支持POST操作,我们之前学的调用API属于GET操作,不同的是,POST操作数据不是放在URL中的,而是放在表单中提交的
所以程序的实现,需要构建一个FormBody表单对象,用于放置表单数据,核心代码如下
Builder builder = new FormBody.Builder();
// 设置数据,第一个参数是数据名,第二个参数是数据值
builder.add("", "");
FormBody formBody = builder.build();Request request = new Request.Builder().url(url).post(formBody).build();
示例:发送表单数据到gitee网站,完成登录
package com.web.post;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.FormBody.Builder;
import okhttp3.OkHttpClient;
import okhttp3.Request;import java.io.IOException;
import java.util.Map;public class FormPost {public String postContent(String url, Map<String,String> formData){OkHttpClient okHttpClient = new OkHttpClient();//post方式提交数据Builder builder = new FormBody.Builder();//放入表单数据for (String key : formData.keySet()) {builder.add(key,formData.get(key));}//构建FormBody对象FormBody formBody = builder.build();//指定Post方式提交formBodyRequest request = new Request.Builder().url(url).post(formBody).build();//使用client 去请求Call call = okHttpClient.newCall(request);//返回结果字符串String result = null;try {result = call.execute().body().string();} catch (IOException e) {e.printStackTrace();}return result;}}
package com.web.post;import java.util.HashMap;
import java.util.Map;public class Demo {public static void main(String[] args) {String url = "https://gitee.com/login";FormPost formPost = new FormPost();Map<String,String> formDate = new HashMap<>();formDate.put("user[login]","1781125992");String content = formPost.postContent(url,formDate);System.out.println("API调用结果");System.out.println(content);}
}
运行结果提示失败,原因是gitee对密码做了特殊加密,所以失败,但是gitee已经收到了请求,只是判断登录没有成功而已
三.Request Response对象
1.Response-网页
上文我们学习了java中使用Okhttp3库请求网页或者调用API的知识,使用一条语句执行调用请求,并且返回字符串:
call.execute().body().string()
实际上,除了具体返回结果,我们还关心:http状态码
状态码是用一个数字直观反应了本次请求的状况,例如常见的200表示请求成功,404表示出错
为了获取状态码。可以使用语句
call.execute().code()
但是通常还要读取响应内容,但是又不能执行两次请求,所以代码应该优化为:
import okhttp3.Response;
//执行请求
Response rep = call.execute();
//获取响应状态码
int code = rep.code();
//获取响应内容
String content = rep.body().string();
2.Response-非文本文件
实际上,okhttp3库不仅可以请求网页、API、也可以请求图片、excel等各种文件
3.Response-JSON
前面的学习中,我们会用okhttp3库获取请求返回的内容。无论是文本文件,还是二进制文件
以后我们还会遇到一种文本内容是JSON格式
参数对象 ==>JSON格式字符串 需要用到fastjson库
JSON格式数据==>Java对象 JSON.parseObject()
实战:请求JSON数据
package com.web.requestjson; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import java.io.IOException;public class ApiAsker {public String getContent(String url){OkHttpClient okHttpClient = new OkHttpClient();Request request = new Request.Builder().url(url).build();Call call = okHttpClient.newCall(request);String result = null;Response response = null;try {response = call.execute();result = response.body().string();} catch (IOException e) {e.printStackTrace();}return result;} }
package com.web.requestjson; import com.alibaba.fastjson.JSON; import java.util.Map;public class Demo {public static void main(String[] args) {ApiAsker apiAsker = new ApiAsker();String url = "http://ip-api.com/json/";String content = apiAsker.getContent(url);Map contentObj = JSON.parseObject(content, Map.class);System.out.println(contentObj);} }
打印结果:
{zip=, country=China, city=Pingdingshan, org=China Mobile, timezone=Asia/Shanghai, regionName=Henan, isp=China Mobile communications corporation, query=120.219.16.129, lon=113.3016, as=AS24445 Henan Mobile Communications Co.,Ltd, countryCode=CN, region=HA, lat=33.7347, status=success}
4.解析JSON对象
在开发过程中,我们经常会遇到多层嵌套结构的JSON数据
例如:
{"code": 0,"data": {"ip": "117.89.35.58","country": "中国","area": "","region": "江苏","city": "南京","county": "XX","isp": "电信","country_id": "CN","area_id": "","region_id": "320000","city_id": "320100","county_id": "xx","isp_id": "100017"}
}
我们只需要多次的取出嵌套的Map对象即可:
Map contentObj = JSON.parseObject(content, Map.class);
Map dataObj = (Map)contentObj.get("data");
String city = (String)dataObj.get("city");
由于Map可以存储任何对象,所以从Map中get()到对象必须指定其实际的类型:(Map)、(String)
四.Headers
1.User-Agent
我们学了Okhttp3库请求网页,API,也会解析JSON格式的文本
但是不一定任何请求都能够成功,这是因为像某宝这样的大型网站,处于安全等各种因素的考虑,会对请求进行比较严格的校验,其中一个重要的校验,是判断请求是否真的来自一个真实的浏览器而不是Java程序、API服务器
判断请求是否真的来自一个真实的浏览器,需要从HTTP消息头(Headers)中取得User-Agent信息后,才能判断
HTTP header
HTTP消息头Headers是HTTP协议的一项重要内容,作用是在发起请求的时候,除了请求参数外,可以附加更多的信息,只要记住,Headers信息并不是写在URL中的,属于隐藏的数据,不能直观看到
User-Agent
User-Agent是存放在Headers中的一种数据信息,作用是在指定URL发送请求的时候,告诉服务端当前用户的浏览器类型,版本,甚至操作系统、CPU等非隐私的技术信息
服务器从Headers中的User-Agent信息获取到浏览器类型、版本等数据后,就认为是一个浏览器请求的环境了,就会给出响应
所以,我们只要在程序代码中,附加上User-Agent信息,就能允许成功了。当然,这里的User-Agent是模拟的。
模拟win7+chrome环境,User-Agent的写法如下:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1
Okhttp3库支持Headers只需要在构建Request对象的时候,调用addHeader()方法即可:
Request request = new Request.Builder().url(ur;).addHeader("User-Agent","").build();
2.Referer
以上学了设置User-Agent解决程序请求HTTP不成功的情况,是类似于模拟一个浏览器环境去请求
有时候我们看到图片无法正常显示,这个是因为图片做了防盗链
防盗链
因为浏览器在请求网页中的图片(或者其他任何文件)时,会自动在HTTP消息头Headers中,加一个Referer信息,表示请求的来源(或者可以理解为图片的上级是网页)。
浏览器自动添加Referer是业界规范
即浏览器自动告诉图片服务器,从当前网址请求此图片,这是图片服务器拒绝了访问,因为服务器的规则是不允许其他网站访问图片。
为什么直接贴网址可以访问?
因为直接拷贝网址,黏贴到浏览器地址栏,就没有了来源了,此时不是网页中加载图片,而是浏览器直接加载图片,图片没有上级。浏览器只是收集了一些信息提交到服务器,并不能决定是否能看到图片
程序中的Referer
为了模拟浏览器自动加Referer信息的行为,可以调用语句
Request request = new Request.Builder().url(url).addHeader("Referer", "").build();
但是仍然是报错
解决方案是:需要把Referer信息设置为图片原始使用的网站
3.Host
Host也是Headers中非常重要的信息之一。
Host表示当前请求的域名,虽然这个域名已经存在于URL中,但是遇到复杂的场景,例如使用代理服务器,或者URL中不写域名而是写IP地址进行请求等,设置Host就非常有用了
五.下载文件、图片
1.下载文件
写入文本文件
package com.web.filewrite;import java.io.File;
import java.io.FileWriter;
import java.io.IOException;public class Demo {public static void main(String[] args) {//创建文件对象File file = new File("7.26.txt");String content = "7月完成任务,八月继续加油";{try {FileWriter fileWriter = new FileWriter(file.getName());//写入内容fileWriter.write(content);//关闭写入操作fileWriter.close();} catch (IOException e) {e.printStackTrace();}}}
}
写入二进制文件
package com.web.filewrite;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;public class Demo1 {public static void main(String[] args) {// 文件对象File file = new File("china-city-list.xlsx");// 写文件FileOutputStream fos = null;try {fos = new FileOutputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();}//data是字节数组fos.write(data);
// 必须刷新并关闭fos.flush();fos.close();}
}
2.下载图片
下载图片与下载其他文件别无二致。图片都是二进制文件,直接用一个字节数组接受即可
package com.web.get;public class Demo {public static void main(String[] args) {GetPage getPage = new GetPage();byte[]content= getPage.getContent("https://img1.baidu.com/it/u=2020082651,1869885258&fm=253&fmt=auto&app=138&f=JPEG?w=519&h=500");System.out.println(content.length);}
}
package com.web.get;import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;import java.io.IOException;public class GetPage {public byte[] getContent(String url){//实例出okhttp3库对象,可以快速实现http调用OkHttpClient okHttpClient = new OkHttpClient();//定义一个请求配置urlRequest request = new Request.Builder().url(url).build();//使用client去请求Call call = okHttpClient.newCall(request);//返回结果字符串byte[] result = null;try {result = call.execute().body().bytes();} catch (Exception e) {e.printStackTrace();}//返回结果return result;}
}
3.解析Excel
Java很强大,已经有库可以操作excel文件了
easyexcel是阿里巴巴出品的快速,简单操作excel文件的库。使用前必须在pom.xml文件中加入
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version>
</dependency>
调用库
excel文件是多sheet模式的,每个sheet实际上是一个表格,表格又分为行和列
所以解析Excel的路径是:sheet -->row-->column
计算机中,第一个单元格的位置是0,第一个sheet、row、column的位置都是0
import com.alibaba.excel.EasyExcel;
import java.util.Map;
import java.util.List;// 读取第一个sheet
List<Map<Integer, String>> sheetDatas = EasyExcel.read("xzq_201907.xlsx").sheet(0).doReadSync();// List 中每个元素表示一行
for (Map<Integer, String> rowData : sheetDatas) {// Map 中用序号指代每一列for (Integer index : rowData.keySet()) {// 列值String columnValue = rowData.get(index); //根据列号遍历列值}
}
六.cookie & session
1.cookie
所谓cookie就是存在客户端浏览器的一段文本内容。以key=value的格式存储一条数据;多条数据之间用分号分开,cookie的核心功能是存储登录数据额外可以存储一些小数据。
2.session
未更新,敬请期待~~~
新Java网络编程(更新中)相关推荐
- java网络编程Socket中SO_LINGER选项的用法解读
http://blog.sina.com.cn/s/blog_6b1990eb0101171o.html 1:设置该选项: public void setSoLinger(boolean on, in ...
- 用java网络编程中的TCP方式上传文本文件及出现的小问题
自己今天刚学java网络编程中的TCP传输,要用TCP传输文件时,自己也是遇到了一些问题,抽空把它整理了一下,供自己以后参考使用. 首先在这个程序中,我用一个客户端,一个服务端,从客户端上传一个文本文 ...
- 【Java网络编程与IO流】Java中IO流分为几种?字符流、字节流、缓冲流、输入流、输出流、节点流、处理流
Java网络编程与IO流目录: [Java网络编程与IO流]Java中IO流分为几种?字符流.字节流.缓冲流.输入流.输出流.节点流.处理流 [Java网络编程与IO流]计算机网络常见面试题高频核心考 ...
- 【Java网络编程与IO流】Java之Java Servlet详解
Java网络编程与IO流目录: [Java网络编程与IO流]Java中IO流分为几种?字符流.字节流.缓冲流.输入流.输出流.节点流.处理流 [Java网络编程与IO流]计算机网络常见面试题高频核心考 ...
- Java SE基础(更新中)
Java的运行机制 Java SE基础(更新中) 基本语法 大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的. 类名:对于所有的类来说,类名的首字母应该大写 ...
- JAVA网络编程知识学习
JAVA网络编程知识学习 学习目标 第一章 网络编程入门 1.1软件结构 1.2 网络通信协议 1.3 协议分类 1.4 网络编程三要素 协议 IP地址 IP地址分类 常用命令 端口号 InetAdd ...
- Java 网络编程系列之 NIO
Java 网络编程系列之 NIO 第 1 章Java NIO 概述 1.1 IO 概述 IO 的操作方式 1.2 阻塞 IO (BIO) 1.3 非阻塞 IO(NIO) 1.4 异步非阻塞 IO(AI ...
- Java 网络编程基础知识
Java 网络编程基础知识 基础概念 计算机网络的基本概念 网络:多台计算机使用网络设备互联在一起,计算机之间可以进行通信,这样就组成了一个计算机网络. 网络设备:集线器(HUB),路由器,交 ...
- Java学习总结:52(Java网络编程)
Java网络编程 开发第一个网络程序 java.net包提供了网络编程有关的开发工具类,在此包中有一下两个主要的核心操作类. ServerSocket类:是一个封装支持的TCP协议的操作类,主要工作在 ...
最新文章
- kaptcha验证码实现,配合spring boot使用
- OpenCV优化:图像的遍历4种方式
- 知乎:fastjson 这么快,为啥老外还是热衷 jackson?
- 转换输入文本中的回车和空格
- netfilter/iptables全攻略
- python中 1.34e3_Python快速编程入门——第2章 Python基础语法
- 【资源】吴恩达新书《Machine Learning Yearning》完整中文版免费下载
- python os.forkos.wait
- 我很生气,帮了不足一个月就离开了
- 记录一次多表关联查询
- input输入框计算总和
- excel mysql 财务_excel函数 数据库 财务函数 统计函数 信息函数
- Python破解zip文件解压密码
- 雅诗兰黛公司实现里程碑式的气候目标 – 净零碳排放、RE100 – 并制定新的科学碳目标
- MATLAB画个直方图
- C++函数重载(6) - main函数重载
- 开发数据可视化,有哪些数据可视化表现形式?
- OpenCV中图像的存储格式(Python版本)
- GROUP Function
- python基础之浅谈布尔类型的变量