Netty源码解析之 java网络编程篇(3)


目录

  1. http协议是个什么东西
  2. http的请求类型都有哪些
  3. 常见的HTTP首部
  4. HTTP请求体
  5. HTTP响应体
  6. HTTP常见的响应状态码
  7. HTTP的cookieg管理

HTTP协议

HTTP是一种通用的网络数据传输格式,它的传输内容不仅仅局限于HTML文件或者图片,所有可以用字节序列表示的数据都可以使用HTTP进行传输。

HTTP通过TCP/IP进行数据传输,如果忽略底层的TCP协议的握手和挥手的细节,对于从客户端到服务器的每一个请求和请求的响应,在HTTP1.0有下面几个步骤:

  1. 默认情况下,客户端在端口80开启与服务器的一个TCP连接,当然也可以指定其他的端口。
  2. 客户端向服务器发送消息,请求指定路径上的资源。一个HTTP请求包括一个首部,可选项包括一个空行和这次请求的数据。
  3. 服务器向客户端发送响应。响应以响应码开头,接着是包含元数据的首部,可选项包括一个空行以及所请求的文档数据或者错误信息。
  4. 服务器关闭TPC连接。

在HTTP1.1(目前最常用的就是HTTP1.1)以及以后的HTTP版本中,可以通过一个TCP连接连续发送多个请求和接收多个响应。

也就是说,上面的1和4步骤中间的2和3步骤可以反复执行多次。另外,HTTP1.1中,请求数据和响应数据可以分块发送,提高了扩展性。

HTTP请求方法

HTTP请求方法 描述 是否安全 是否幂等
GET 通常用于请求服务器获取某个资源
HEAD 类似于GET,但是响应结果中不包含响应体,只包含协议信息和首部,通常用于测试资源是否存在或者是否被修改 -
POST 客户端向服务器提交数据(支持HTML的表单数据),可能会导致新的资源的建立或者已有资源的修改
PUT 从客户端向服务器传送的数据取代指定的文档的内容(全部取代)
PATCH 客户端向服务器传送的数据取代指定的文档的内容(部分取代)
TRACE 回显客户端请求服务器的原始请求报文,用于"回环"诊断 -
OPTIONS 请求服务器获取服务器支持的各种功能,可以询问服务器支持什么类型的HTTP方法,一般用于性能测试 -
DELETE 请求服务器删除指定的资源

安全 : 意味着使用该种HTTP请求方法不会发生任何数据的修改或者更新动作,也就是请求多次也不会影响到资源的状态。

幂等 : 意味着使用该HTTP请求方法请求多次HTTP调用,无论调用多少次,请求结果或者资源的状态是一样的。

HTTP方法的安全性和幂等性是我们在设计HTTP接口时候需要重点考虑的两个因素。

上面提到的POST和PUT方法的功能可以理解为相同的,两者的主要区别在于POST不是幂等的,而PUT是幂等的。

在目前的Web开发中,POST方法已经被滥用,一般很少人会使用PUT,除非是推崇RESTFUL风格编程。

PUT方法和PATCH方法的功能类似,都是用客户端请求的数据去替换掉服务器中指定文档中的内容,不过PUT方法是全部替换,而PATCH方法是部分替换。

常见的HTTP首部

字段 首部类型 描述
User-Agent 请求 用户代理,用于告知服务器当前客户端使用的是什么浏览器
Host 请求 用于指定接收该请求的服务器的主机名和端口号
Accept-Charset 请求 告知服务器客户端可以接收和处理哪些字符集
Accept-Encoding 请求 告知服务器客户端可以接收和处理哪些编码方式
Accept-Language 请求 告知服务器客户端可以接收和处理哪些语言
Accept 请求 告知服务器客户端可以接收和处理哪些媒体类型
Referer 请求 提供了包含当前请求的URL的文档的URL
Cookie 请求 客户端通过它向服务器传送一个或者多个令牌,原则上Cookie并不是安全的首部,Cookie的内容也会缓存在客户端。
Cache-Control 请求 告知服务器对当前的请求的响应结果进行缓存相关操作
Content-Type 通用 告知服务器或者客户端当前请求或者响应结果的内容(媒体)类型
Content-Length 通用 告知服务器或者客户端当前请求或者响应数据体的长度
Connection 请求 否需要持久连接,如果指定为Keep-Alive,可以提供持久连接
Origin 请求 指明当前的请求是一个针对跨域资源共享的请求
Access-Control-Allow-Origin 响应 表示服务器允许的该跨域资源共享的请求来源
Server 响应 用于告知客户端服务器的相关信息
Set-Cookie 响应 Cookie对应,表示服务器设置成功的Cookie
Content-Encoding 响应 Accept-Encoding对应,用于服务器告知客户端当前响应结果的内容编码
Content-Language 响应 与Accept-Language对应,用于服务器告知客户端当前响应结果的内容语言

其中 Accept的值可以是以下八种顶级的类型

text/* 表示人可读的文字。
image/* 表示图片。
model/* 表示3D模型,如VRML文件。
audio/* 表示音频。
video/* 表示多媒体图片、视频,也可能是音频。
application/* 表示二进制数据。
message/* 表示协议特定的信封,如Email消息和HTTP响应。
muitipart/* 表示多个文档和资源的容器。

HTTP请求体

如果采用GET请求方法,只需要向远处服务器提供URL,URL中的路径和查询字符串就可以匹配到需要查询的资源。

但是URL中无法提供详细的客户端信息,像POST和PUT这些请求方法所携带的数据体有可能比较大。

因此HTTP需要请求体。HTTP请求体包括下面四个部分:

  • 一个起始请求行,包括HTTP方法、路径、查询字符串以及HTTP版本。
  • HTTP请求的首部。
  • 一个空行(两个连续的回车或者换行对)。
  • 请求数据体。
GET /wp-admin/admin-ajax.php?postviews_id=23996&action=postviews&_=1538708851063 HTTP/1.1
Host: www.importnew.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Referer: http://www.importnew.com/23996.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

postviews_id=23996&action=postviews&_=1538708851063

HTTP响应体

响应体和请求体的格式类似,主要是返回服务器的响应数据到客户端,包括服务器的一些信息和响应数据体。HTTP响应体主要包括下面的四个部分:

1、一个起始响应行,包括HTTP版本、状态码、状态码描述。

2、HTTP响应的首部。

3、一个空行(两个连续的回车或者换行对)。

4、响应数据体。

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Oct 2018 03:07:37 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=2
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.3
X-Robots-Tag: noindex
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip

2995

Keep-Alive

在使用HTTP1.0的时候会为每个请求打开一个新的TCP连接,实际上,这导致了一个典型Web会话中打开和关闭所有连接所花费的事件远远大于实际传输数据所消耗的时间,特别是响应结果包含很多小文档的会话。对于使用SSL或者TLS加密的HTTPS连接,这个问题更加严重,因为建立一个安全的Socket的握手过程远比建立常规的Socket需要更多的工作。

在HTTP1.1和后面的版本中,服务器不必在返送响应之后就关闭连接。已经建立的连接可以保持打开,在同一个Socket上等待来自客户端的新请求。简单来说,就是可以在一个TCP连接上连续发送多个请求和连续进行多个请求的响应。

客户端可以在HTTP请求首部中添加一个Connection请求头,指定值为Keep-Alive,这样就能实现Socket的重用:

Connection: Keep-Alive
HTTP1.1或者之后的版本,Keep-Alive是默认开启的,不需要显式指定,如果需要关闭可以设置为close:

Connection: close
一旦开启了Keep-Alive,服务器在关闭一个Socket连接之前,如果有新的客户端再次连接到服务器,那么就是重用Socket。在JDK中可以通过系统属性来控制如果使用HTTP的Keep-Alive:

http.keepAlive:默认值为true,默认开启HTTP的Keep-Alive。

http.maxConnections:同时保持打开的Socket数量的最大值,默认值为5。

http.keepAlive.remainingData:默认值为false,如果设置为true,则JDK在丢弃连接之后会完成剩余数据的清理。

sun.net.http.errorstream.enableBuffering:默认值为false,如果设置为true,则尝试缓存400和500状态码的相对小的错误流,从而能释放连接以备后续使用。

sun.net.http.errorstream.bufferSize:为缓存错误流的缓冲区的字节大小,默认值为4096字节,只有上一项为true的时候才有意义。

sun.net.http.errorstream.timeout:默认值为300ms,读取错误流超时的毫秒数。

常见的HTTP状态码

简单的说

  • 响应码100-199表示一个提供信息的响应。
  • 响应码200-299表示请求成功。
  • 响应码300-399表示重定向。
  • 响应码400-499表示一个客户端引发的错误。
  • 响应码500-599表示一个服务器引发的错误。
状态码 状态码消息 含义 HttpURLConnection中的常量 简单描述
1xx - 信息状态码。 - 不常见,暂不考虑
100 Continue 服务器准备接受请求主体,客户端发送请求主体;这允许客户端在请求发送大量数据之前询问服务器是否接受请求。 - 不常见,暂不考虑
101 Switching Protocols 服务器接受客户端在Upgrade首部字段中要求改变应用的协议请求,如从HTTP转换为WebSockets。 - 不常见,暂不考虑
2xx - 表示请求成功。 - -
200 OK 最常见的响应码,代表请求成功。如果请求方法是GET或者POST,所请求的数据与正常的首部都包含在响应体中。如果请求方法是HEAD,则只包含首部信息。 HTTP_OK 处理请求成功
201 Created 服务器已经在响应体中指定的URL创建了对应的资源。客户端现在应当尝试加载该URL。这个响应码只在响应POST请求时发送。 HTTP_CREATED 创建成功
202 Accepted 表示请求已经被处理,但是处理尚未结束,所以不会返回任何响应数据。 HTTP_ACCEPTED 接受请求
203 Non-Authoritative Information 由缓存代理或者其他本地源返回资源的表示,不能保证是最新的。 HTTP_NOT_AUTHORITATIVE 无权威的返回结果
204 No Content 服务器已经成功处理了该请求,但是没有信息发回给客户端。一般是由于服务器上的表单处理逻辑的问题,只接收数据不返回数据。 HTTP_NO_CONTENT 无返回内容
205 Reset Content 服务器已经成功处理了该请求,但是没有信息发回给客户端。客户端应该清除发送请求的表单信息。 HTTP_RESET 重置内容
206 Partial Content 服务器返回客户端请求的资源的部分内容,而不是整个文档。 HTTP_PARTIAL 部分内容
3xx - 重定向。 - -
300 Multiple Choices 服务器为所请求的文档提供一组不同的表示。 HTTP_MULT_CHOICE 多重选择
301 Moved Permanently 资源已经移动到一个新的URL。客户端应当自动加载这个URL的资源。 HTTP_MOVE_PERM 永久移动
302 Moved Temporarity 资源暂时移动到一个新的URL,但其位置在不久的将来还会再次改变。 HTTP_MOVE_TEMP 临时移动
4xx - 客户端错误 - -
400 Bad Request 客户端向服务器发出的请求使用了不正确的语法。 HTTP_BAD_REQUEST 错误请求
401 Unauthorized 访问这个URL需要身份验证,一般是用户名和口令。 HTTP_UNAUTHORIZED 未授权
403 Forbidden 服务器理解请求,但是有意拒绝进行处理。 HTTP_FORBIDDEN 禁止访问
404 Not Found 最常见的错误响应,指示服务器找不到所请求的资源。 HTTP_NOT_FOUND 未找到资源
405 Method Not Allowed 请求方法不支持用于请求指定的资源。 HTTP_BAD_METHOD 方法禁用
406 Not Acceptable 所请求的资源不能以客户端希望的格式提供,客户端期望的格式由请求HTTP首部Accept字段指定。 HTTP_NOT_ACCEPTABLE 不接受
5xx - 服务端错误 - -
500 Internale Server Error 服务器内部异常。 HTTP_SERVER_ERROR 服务器异常
501 Not Implemented 服务器不具备完成请求的功能。 HTTP_NOT_IMPLEMENTED 尚未实现
502 Bad Gateway 服务器作为网关或代理,从上游服务器收到无效响应。 HTTP_BAD_GATEWAY 错误网关
503 Service Unavailable 服务器暂时无法处理请求,可能是超负荷或者维护等原因。 HTTP_UNAVAILABLE 服务不可用

Cookie和Cookie管理

一般在Servlet应用中,Cookie是识别当前用户,实现持久会话的最佳方式。

从过期时间分类来看,Cookie分为会话Cookie和持久Cookie,会话Cookie的过期时间比较短,持久Cookie的过期时间比较长或者不会过期,Cookie的过期策略等控制应该由服务端控制。

由于Cookie是直接暴露在客户端,一般不能使用Cookie存放敏感的数据,需要存放敏感数据可以考虑使用数据加密处理。

很多网站使用一些小文本串在连接之间存储持久的客户端状态,这些小文本串称为Cookie(中文翻译为:小甜点)。

Cookie在请求和响应的首部从服务器传到客户端,再从客户端传回服务器,服务器使用Cookie来指示sessionID、购物车内容、登录凭据等。

除了简单的name=value对,Cookie可以有多个属性来控制它们的作用域,包括过期日期、路径、域、端口、版本和安全选项。

JDK中java.net.CookieStore类提供了对Cookie的增删查操作,它的默认实现是java.net.InMemoryCookieStore,如果实现CookieStore,JDK中的Cookie默认是存放在内存中的。

另外,java.net.CookieManager内部持有CookiePolicy和CookieStore,定义了一系列管理Cookie的方法,一般通过CookieManager操作Cookie,当然也可以通过实现CookieStore,覆盖默认的CookieManager来实现Cookie的自定义管理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • http协议有http0.9,http1.0,http1.1和http2三个版本,但是现在浏览器使用的是htt...
    一现_阅读 1,863评论 0 3
  • 6.1 公钥密钥加密原理 6.1.1 基础知识 密钥:一般就是一个字符串或数字,在加密或者解密时传递给加密/解密算...
    AndroidMaster阅读 4,011评论 1 8
  • HTTP协议,全称超文本传输协议(HyperText Transfer Protocol),是目前互联网上应用最为...
    darrenW阅读 609评论 0 0
  • 本文是《图解HTTP》读书笔记的第二篇,主要包括此书的第六章内容,因为第六章的内容较多,而且比较重要,所以单独写为...
    lijiankun24阅读 1,364评论 0 6
  • 昨晚有朋友做分享课,因故没去。群里收到如下作业: 今晚讲的后半部分来源于《儿童爱之语》这本书,想...
    陈洁007阅读 397评论 0 1