Java网络通信 – HTTP通信详解

Java网络通信 – HTTP通信详解

一、web及网络基础

1、HTTP概念

HTTP(Hyper Text Transfer Protocol,超文本传输协议)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。它是一个应用层协议,承载于TCP之上。由请求和响应构成,是一个标准的客户端服务器模型 。

2、HTTP在Web应用中的重要性

HTTP协议是整个Web基础,许多应用都离不开对HTTP协议的认识:
WebService = HTTP + XMLReset = HTTP + JSON
各种API的实现:HTTP + XML/JSON
采集、小偷站QQ、迅雷等桌面应用软件

3、网络基础TCP/IP协议

3.1 – 协议的概念:

协议是指计算机通信网络中,两台计算机进行通信,所必须遵循的规定或规则。
计算机网络中有各种各样的协议,比如TCP协议、IP协议、HTTP协议、FTP协议等等,像这样把与互联网相关联的协议集合起来,就成为TCP/IP协议族。

3.2 – TCP/IP的分层管理:

应用层:负责处理特定的应用程序,表现为Http、Http、FTP、DNS等。。
传输层:该层有两种协议:TCP和UDP。对上层应用层提供处于网络连接中两台计算机之间的数据连接。
网络层:表现为IP协。处理网络上流动的数据报。该层协议有:IP、ICMP、IGMP
数据链路层:处理连接网络的硬件部分。包括操作系统、硬件设备驱动、网卡、光纤等。主要表现为识别mac间比特流的传输

4、IP、TCP、DNS与HTTP的密切关系

4.1 – IP协议的概念与作用: 

IP(Internet Protocol),网际协议,位于网络层 把各种数据包传送给对方。最重要的两个条件是IP地址和MAC地址(MAC地址基本不会改变,但可以通过软件改变)

4.2 – TCP协议的概念与作用: 

TCP(Transmission Control Protocol),传输控制协议,位于传输层。提供可靠的字节流服务,通过三次握手策略 (三次握手具体过程见另一个笔记)

4.3 – DNS的概念与作用:

DNS(Domain Name System),域名解析系统,位于应用层。
提供域名到IP地址之间的解析服务

4.4 – HTTP 与 TCP、IP 和 DNS的关系:

HTTP生成请求报文需要通过DNS解析出IP找到服务器,通过TCP传输请求。

4.5 – URL 和 URI 的概念:

URL(Uniform Resource Location),统一资源定位符。它描述一台特定服务器上某特定资源的特定位置。
URI(Uniform Resource Identifier),统一资源标识符。是一个用于标识某一互联网资源名称的字符串。

4.6 – URL 和 URI的关系:

URI用字符串标识某一互联网资源,而URL代表资源的地址,由此可见,URL是URI的子集。

4.7 – URI的格式:

如URI : http://user:pass@www.example.com:80/home/index.html?age=11#mask
http:协议方案名,获取资源是要指定协议类型
user:pass:登录信息(认证),指定用户名和密码,可选。
www.example.com:服务器地址
80:端口号,可选
/home/index.html : 文件(服务器资源)路径
age=11 : 参数,为应用程序提供访问资源所需的附加信息
查询字符串:针对已指定的文件路径内的资源,可以使用查询字符串穿入任意参数,可选(分页case)
mask ( 可选 ): 片段标识符,通常可标记出已获取资源中的子资源(文档内的某一个位置)

二、HTTP的工作流程和报文格式

1、HTTP的工作流程

关于更详细的解读,移步这篇: 输入网址后的一瞬间发生了什么

2、HTTP的请求报文

请求报文的格式 :

请求行 : 请求方式(大写) 请求URL 版本
请求首部 : 名: 值
空行 
报文主体 

请求首部也叫消息头,其中字段名不区分大小写,习惯驼峰式,字段可按任意顺序排列,有些可接受多个值选项,有些字段可出现多次

请求方式 :
GET、POST、HEAD、OPTIONS、DELETE、PUT
默认发GET请求,如在浏览器直接输入地址访问,点超链接访问都是get,用户如想把请求方式改为post,通过更改表单的提交方式实现。 
POST与GET方式的区别:传递参数的方式、传递数据量大小限制

常用请求头

Accept-Charset : 告诉服务器,浏览器支持哪种字符集

Accept-Encoding : 浏览器能够进行解码的数据编码方式,比如gzip

Accept-Language : 浏览器所希望的语言种类

Host:初始URL中的主机和端口,敲黑板!!冒号后面有一个空格,这个在组装请求报文时,尤为重要)

Referer : 包含一个URL,用户从该URL代表的页面发出访问当前请求的页面

Content-Type :内容类型

If-Modified-Since :值为一个GMT标准时间,如果在该时间到目前,请求文件没有更改,则服务器告诉浏览器可以直接从缓存中读取文件

User-Agent :用户的浏览器类型,操作系统等信息

Content-Length :表示请求消息正文的长度

Connection:如果值为Keep-Alive,表示需要持久连接,HTTP 1.1默认进行持久连接

Cookie :这是最重要的请求头信息之一,但是由于该技术存在安全隐患等原因,该功能被Session取代

Date :值为GMT时间,表示请求时间

请求头图示:

一个示例请求报文:

GET /v3/weather/weatherInfo?city=%E9%95%BF%E6%B2%99&key=13cb58f5884f9749287abbead9c658f2 HTTP/1.1
Host: restapi.amap.com

2、HTTP的 响应报文

响应报文的形式:

响应行: 协议版本 状态码 原因短语
响应首部
空行
报文主体

响应状态码:

比较常用的:

200:正常
301:永久重定向
302/307:临时重定向
304:未修改,可以使用缓存,无需再次修改

下面几个是家常便饭的…  (╯‵□′)╯︵┻━┻
403 :资源不可用。服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的WEB访问错误,(9.22更新)或者前端发送的ajax中contentType不符合后端Controller要求,比如后端要求接受xml你却发送json的,也会报错。
404 :资源找不到
500 :服务器内部错误

常用响应头

Location:http://cn.bing.com/ 指示新的资源位置

Server :apache tomcat 指示服务器的类型

Content-Encoding : gzip 服务器发送数据采用的编码类型

Content-Length :80 告诉浏览器正文的长度

Content-Language:zh-cn 服务器发送的文本的语言

Content-Type:text/html;charset=GB2312 服务器发送内容的MIME类型

Last-Modified:GMT时间 文件最后修改的时间

Refresh:1;url=http://www.baidu.com 指示客户端刷新频率,单位是秒

Content-Disposition:attachment;filename=aaa.zip 指示客户端下载文件

Set-Cookie:SS=Q0=5Lb_nQ;path=/search 服务器发送的Cookie

Expires: GMT时间 表示过期时间,其值为0或-1表示禁止缓存

Cache-Control:no-cache(1.1) 表示进制缓存

Connection:close/Keep-Alive

Date: GMT时间

谷歌响应头图示:

一个请求和相应示例:


三、Java中实现Http通信代码时的注意点:

1. 用java写请求头时,注意要用\r\n表示头部参数已写完

2.如果为POST请求,还需要进行body参数的拼装,这里以form表单为例,拼接上面接口的参数。规则就是“键=值”,键值对间用“&”隔开。
如: city=长沙&key=13cb58f5884f9749287abbead9c658f2

3. 写http版本信息注意空格、 Host后面一个冒号加一个空格。

请求头每一行的换行符转为2进制byte后的值为1310,所以读取用下面代码:

do {
    readByte = (byte) in.read();
    Arraylist<Byte>.add( Byte.valueOf( readByte ) );        
    System.out.print(readByte);
} while(readByte != 10); 

或者按行读取 :

InputStreamReader inreader = new InputStreamReader(in , encoding);
char[] buffer = new char[1024];
int len = -1;
while( (len = inreader.read(buffer)) &gt; 0 ){
    String str = new String(buffer, 0, len);
    System.out.println(str);
}

 

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注