者:涤生_Woo
一张图带你看完本篇文章
计算机网络体系结构分层
利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上走。如下:
TCP/IP 通信传输流
如下图所示:
HTTP 请求
在网络体系结构中,包含了众多的网络协议,这篇文章主要围绕 HTTP 协议(HTTP/1.1版本)展开。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。 HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。HTTP包含命令和传输信息,不仅可用于Web访问,也可以用于其他因特网/内联网应用系统之间的通信,从而实现各类应用资源超媒体访问的集成。 我们在浏览器的地址栏里输入的网站地址叫做URL (Uniform Resource Locator,统一资源定位符)。就像每家每户都有一个门牌地址一样,每个网页也都有一个Internet地址。当你在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成漂亮的网页。
HTTP请求响应模型
HTTP通信机制是在一次完整的 HTTP 通信过程中,客户端与服务器之间将完成下列7个步骤:
应用 HTTP 协议时,必定是一端担任客户端角色,另一端担任服务器端角色。仅从一条通信线路来说,服务器端和客服端的角色是确定的。HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
HTTP 是一种无状态协议。协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。 可是随着 Web 的不断发展,我们的很多业务都需要对通信状态进行保存。于是我们引入了 Cookie 技术。有了 Cookie 再用 HTTP 协议通信,就可以管理状态了。
Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
Cookie 的流程
HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。
HTTP 方法
HTTP 协议的初始版本中,每进行一个 HTTP 通信都要断开一次 TCP 连接。比如使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无畏的 TCP 连接建立和断开,增加通信量的开销。 为了解决上述 TCP 连接的问题,HTTP/1.1 和部分 HTTP/1.0 想出了持久连接的方法。其特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。旨在建立一次 TCP 连接后进行多次请求和响应的交互。在 HTTP/1.1 中,所有的连接默认都是持久连接。
持久连接使得多数请求以管线化方式发送成为可能。以前发送请求后需等待并接收到响应,才能发送下一个请求。管线化技术出现后,不用等待亦可发送下一个请求。这样就能做到同时并行发送多个请求,而不需要一个接一个地等待响应了。 比如,当请求一个包含多张图片的 HTML 页面时,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术要比持久连接速度更快。请求数越多,时间差就越明显。
用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文;响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。
HTTP 报文大致可分为报文首部和报文主体两部分。两者由最初出现的空行(CR+LF)来划分。通常,并不一定有报文主体。如下:
HTTP 报文结构
请求报文结构
请求报文的首部内容由以下数据组成:
请求报文的示例,如下:
请求报文示例
响应报文结构
响应报文的首部内容由以下数据组成:
响应报文的示例,如下:
响应报文示例
举个栗子,下面是一个 HTTP 请求的报文:
GET /index.htm HTTP/1.1
Host: sample.com
其中,下面的这行就是请求行,
GET /index.htm HTTP/1.1
综合来看,大意是请求访问某台 HTTP 服务器上的 /index.htm 页面资源。
同样举个栗子,下面是一个 HTTP 响应的报文:
HTTP/1.1 200 OK
Date: Mon, 10 Jul 2017 15:50:06 GMT
Content-Length: 256
Content-Type: text/html
<html>
...
其中,下面的这行就是状态行,
HTTP/1.1 200 OK
先来回顾一下首部字段在报文的位置,HTTP 报文包含报文首部和报文主体,报文首部包含请求行(或状态行)和首部字段。 在报文众多的字段当中,HTTP 首部字段包含的信息最为丰富。首部字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信息。使用首部字段是为了给客服端和服务器端提供报文主体大小、所使用的语言、认证信息等内容。
首部字段名 冒号 字段值 Content-Type : text/html Keep-Alive : timeout=30, max=120
首部字段根据实际用途被分为以下4种类型:
类型 描述 通用首部字段 请求报文和响应报文两方都会使用的首部 请求首部字段 从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息 响应首部字段 从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。 实体首部字段 针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的的信息。
首部字段名 说明 Cache-Control 控制缓存的行为 Connection 逐挑首部、连接的管理 Date 创建报文的日期时间 Pragma 报文指令 Trailer 报文末端的首部一览 Transfer-Encoding 指定报文主体的传输编码方式 Upgrade 升级为其他协议 Via 代理服务器的相关信息 Warning 错误通知
通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。
可用的指令按请求和响应分类如下: 缓存请求指令
指令 参数 说明 no-cache 无 强制向服务器再次验证 no-store 无 不缓存请求或响应的任何内容 max-age=[秒] 必需 响应的最大Age值 max-stale(=[秒]) 可省略 接收已过期的响应 min-fresh=[秒] 必需 期望在指定时间内的响应仍有效 no-transform 无 代理不可更改媒体类型 only-if-cached 无 从缓存获取资源 cache-extension - 新指令标记(token)
缓存响应指令
指令 参数 说明 public 无 可向任意方提供响应的缓存 private 可省略 仅向特定用户返回响应 no-cache 可省略 缓存前必须先确认其有效性 no-store 无 不缓存请求或响应的任何内容 no-transform 无 代理不可更改媒体类型 must-revalidate 无 可缓存但必须再向源服务器进行确认 proxy-revalidate 无 要求中间缓存服务器对缓存的响应有效性再进行确认 max-age=[秒] 必需 响应的最大Age值 s-maxage=[秒] 必需 公共缓存服务器响应的最大Age值 cache-extension - 新指令标记(token)
public 指令 Cache-Control: public 当指定使用 public 指令时,则明确表明其他用户也可利用缓存。
private 指令 Cache-Control: private 当指定 private 指令后,响应只以特定的用户作为对象,这与 public 指令的行为相反。缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。
no-cache 指令 Cache-Control: no-cache
Cache-Control: no-cache=Location 由服务器返回的响应中,若报文首部字段 Cache-Control 中对 no-cache 字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
no-store 指令 Cache-Control: no-store 当使用 no-store 指令时,暗示请求(和对应的响应)或响应中包含机密信息。因此,该指令规定缓存不能在本地存储请求或响应的任一部分。 注意:no-cache 指令代表不缓存过期的指令,缓存会向源服务器进行有效期确认后处理资源;no-store 指令才是真正的不进行缓存。
s-maxage 指令 Cache-Control: s-maxage=604800(单位:秒)
max-age 指令 Cache-Control: max-age=604800(单位:秒)
min-fresh 指令 Cache-Control: min-fresh=60(单位:秒) min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。
max-stale 指令 Cache-Control: max-stale=3600(单位:秒)
only-if-cached 指令 Cache-Control: only-if-cached 表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源的有效性。
must-revalidate 指令 Cache-Control: must-revalidate 使用 must-revalidate 指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍有效。另外,使用 must-revalidate 指令会忽略请求的 max-stale 指令。
proxy-revalidate 指令 Cache-Control: proxy-revalidate proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
no-transform 指令 Cache-Control: no-transform 使用 no-transform 指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。这样做可防止缓存或代理压缩图片等类似操作。
Cache-Control: private, community="UCI" 通过 cache-extension 标记(token),可以扩展 Cache-Control 首部字段内的指令。上述 community 指令即扩展的指令,如果缓存服务器不能理解这个新指令,就会直接忽略掉。
Connection 首部字段具备以下两个作用:
控制不再转发的首部字段 Connection: Upgrade 在客户端发送请求和服务器返回响应中,使用 Connection 首部字段,可控制不再转发给代理的首部字段,即删除后再转发(即Hop-by-hop首部)。
管理持久连接 Connection: close HTTP/1.1 版本的默认连接都是持久连接。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 close。 Connection: Keep-Alive HTTP/1.1 之前的 HTTP 版本的默认连接都是非持久连接。为此,如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。
表明创建 HTTP 报文的日期和时间。 Date: Mon, 10 Jul 2017 15:50:06 GMT HTTP/1.1 协议使用在 RFC1123 中规定的日期时间的格式。
Pragma 首部字段是 HTTP/1.1 版本之前的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。 Pragma: no-cache
Cache-Control: no-cache
Pragma: no-cache
Trailer: Expires 首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。可应用在 HTTP/1.1 版本分块传输编码时。
Transfer-Encoding: chunked
Upgrade: TSL/1.0 用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
Via: 1.1 a1.sample.com(Squid/2.7)
该首部字段通常会告知用户一些与缓存相关的问题的警告。 Warning 首部字段的格式如下: Warning:[警告码][警告的主机:端口号] "[警告内容]"([日期时间]) 最后的日期时间可省略。 HTTP/1.1 中定义了7种警告,警告码对应的警告内容仅推荐参考,另外,警告码具备扩展性,今后有可能追加新的警告码。
警告码 警告内容 说明 110 Response is stale(响应已过期) 代理返回已过期的资源 111 Revalidation failed(再验证失败) 代理再验证资源有效性时失败(服务器无法到达等原因) 112 Disconnection operation(断开连接操作) 代理与互联网连接被故意切断 113 Heuristic expiration(试探性过期) 响应的试用期超过24小时(有效缓存的设定时间大于24小时的情况下) 199 Miscellaneous warning(杂项警告) 任意的警告内容 214 Transformation applied(使用了转换) 代理对内容编码或媒体类型等执行了某些处理时 299 Miscellaneous persistent warning(持久杂项警告) 任意的警告内容
首部字段名 说明 Accept 用户代理可处理的媒体类型 Accept-Charset 优先的字符集 Accept-Encoding 优先的内容编码 Accept-Language 优先的语言(自然语言) Authorization Web认证信息 Expect 期待服务器的特定行为 From 用户的电子邮箱地址 Host 请求资源所在服务器 If-Match 比较实体标记(ETag) If-Modified-Since 比较资源的更新时间 If-None-Match 比较实体标记(与 If-Macth 相反) If-Range 资源未更新时发送实体 Byte 的范围请求 If-Unmodified-Since 比较资源的更新时间(与 If-Modified-Since 相反) Max-Forwards 最大传输逐跳数 Proxy-Authorization 代理服务器要求客户端的认证信息 Range 实体的字节范围请求 Referer 对请求中 URI 的原始获取方 TE 传输编码的优先级 User-Agent HTTP 客户端程序的信息
Accept: text/html, application/xhtml+xml, application/xml; q=0.5
Accept-Charset: iso-8859-5, unicode-1-1; q=0.8 Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。同样使用 q=[数值] 来表示相对优先级。
Accept-Encoding: gzip, deflate Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先顺序,并可一次性指定多种内容编码。同样使用 q=[数值] 来表示相对优先级。也可使用星号(*)作为通配符,指定任意的编码格式。
Accept-Lanuage: zh-cn,zh;q=0.7,en=us,en;q=0.3 告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级,可一次性指定多种自然语言集。同样使用 q=[数值] 来表示相对优先级。
Authorization: Basic ldfKDHKfkDdasSAEdasd==告知服务器用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中。共用缓存在接收到含有 Authorization 首部字段的请求时的操作处理会略有差异。
Expect: 100-continue 告知服务器客户端期望出现的某种特定行为。
From: Deeson_Woo@163.com 告知服务器使用用户代理的电子邮件地址。
Host: www.jianshu.com
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
If-Match: "123456"
If-Modified-Since: Mon, 10 Jul 2017 15:50:06 GMT
If-None-Match: "123456" 首部字段 If-None-Match 属于附带条件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的实体标记(ETag)值与请求资源的 ETag 不一致时,它就告知服务器处理该请求。
If-Range: "123456"
If-Unmodified-Since: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应返回。
Max-Forwards: 10 通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max-Forwards 的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards 的值减 1 后重新赋值。当服务器接收到 Max-Forwards 值为 0 的请求时,则不再进行转发,而是直接返回响应。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
Range: bytes=5001-10000
Referer: http://www.sample.com/index.html 首部字段 Referer 会告知服务器请求的原始资源的 URI。
TE: gzip, deflate; q=0.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101
首部字段名 说明 Accept-Ranges 是否接受字节范围请求 Age 推算资源创建经过时间 ETag 资源的匹配信息 Location 令客户端重定向至指定 URI Proxy-Authenticate 代理服务器对客户端的认证信息 Retry-After 对再次发起请求的时机要求 Server HTTP 服务器的安装信息 Vary 代理服务器缓存的管理信息 WWW-Authenticate 服务器对客户端的认证信息
Accept-Ranges: bytes
Age: 1200
ETag: "usagi-1234"
Location: http://www.sample.com/sample.html
Proxy-Authenticate: Basic realm="Usagidesign Auth"
Retry-After: 180
Server: Apache/2.2.6 (Unix) PHP/5.2.5 首部字段 Server 告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。
Vary: Accept-Language
WWW-Authenticate: Basic realm="Usagidesign Auth" 首部字段 WWW-Authenticate 用于 HTTP 访问认证。它会告知客户端适用于访问请求 URI 所指定资源的认证方案(Basic 或是 Digest)和带参数提示的质询(challenge)。
首部字段名 说明 Allow 资源可支持的 HTTP 方法 Content-Encoding 实体主体适用的编码方式 Content-Language 实体主体的自然语言 Content-Length 实体主体的大小(单位:字节) Content-Location 替代对应资源的 URI Content-MD5 实体主体的报文摘要 Content-Range 实体主体的位置范围 Content-Type 实体主体的媒体类型 Expires 实体主体过期的日期时间 Last-Modified 资源的最后修改日期时间
Allow: GET, HEAD
Content-Encoding: gzip
Content-Language: zh-CN 首部字段 Content-Language 会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。
Content-Length: 15000 首部字段 Content-Length 表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用 Content-Length首部字段。
Content-Location: http://www.sample.com/index.html 首部字段 Content-Location 给出与报文主体部分相对应的 URI。和首部字段 Location 不同,Content-Location 表示的是报文主体返回资源对应的 URI。
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
Content-Range: bytes 5001-10000/10000 针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
Content-Type: text/html; charset=UTF-8 首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字段 Accept 一样,字段值用 type/subtype 形式赋值。参数 charset 使用 iso-8859-1 或 euc-jp 等字符集进行赋值。
Expires: Mon, 10 Jul 2017 15:50:06 GMT
Last-Modified: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 Last-Modified 指明资源最终修改的时间。一般来说,这个值就是 Request-URI 指定资源被修改的时间。但类似使用 CGI 脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。
首部字段名 说明 首部类型 Set-Cookie 开始状态管理所使用的 Cookie 信息 响应首部字段 Cookie 服务器接收到的 Cookie 信息 请求首部字段
Set-Cookie: status=enable; expires=Mon, 10 Jul 2017 15:50:06 GMT; path=/;
下面的表格列举了 Set-Cookie 的字段值。
属性 说明 NAME=VALUE 赋予 Cookie 的名称和其值(必需项) expires=DATE Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) path=PATH 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录) domain=域名 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie的服务器的域名) Secure 仅在 HTTPS 安全通信时才会发送 Cookie HttpOnly 加以限制,使 Cookie 不能被 JavaScript 脚本访问
Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。
Cookie 的 secure 属性用于限制 Web 页面仅在 HTTPS 安全连接时,才可以发送 Cookie。
Cookie: status=enable 首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。接收到多个 Cookie 时,同样可以以多个 Cookie 形式发送。
HTTP 首部字段是可以自行扩展的。所以在 Web 服务器和浏览器的应用上,会出现各种非标准的首部字段。 以下是最为常用的首部字段。
X-Frame-Options: DENY 首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。首部字段 X-Frame-Options 有以下两个可指定的字段值:
X-XSS-Protection: 1 首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。首部字段 X-XSS-Protection 可指定的字段值如下:
DNT: 1 首部字段 DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。首部字段 DNT 可指定的字段值如下:
由于首部字段 DNT 的功能具备有效性,所以 Web 服务器需要对 DNT做对应的支持。
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND 首部字段 P3P 属于 HTTP 响应首部,通过利用 P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。 要进行 P3P 的设定,需按以下操作步骤进行:
类别 原因短语 1xx Informational(信息性状态码) 接收的请求正在处理 2xx Success(成功状态码) 请求正常处理完毕 3xx Redirection(重定向状态码) 需要进行附加操作以完成请求 4xx Client Error(客户端错误状态码) 服务器无法处理请求 5xx Server Error(服务器错误状态码) 服务器处理请求出错
我们可以自行改变 RFC2616 中定义的状态码或者服务器端自行创建状态码,只要遵守状态码的类别定义就可以了。
HTTP 状态码种类繁多,数量达几十种。其中最常用的有以下 14 种,一起来看看。
表示从客户端发来的请求在服务器端被正常处理了。
表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 首部字段指定范围的实体内容。
永久性重定向。表示请求的资源已被分配了新的 URI。以后应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。
临时重定向。该状态码与 302 Found 有着相同的含义。
表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出详细的拒绝理由,当然也可以在响应报文的实体主体部分对原因进行描述。
表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由的时候使用。
表明服务器端在执行请求时发生了错误。也可能是 Web 应用存在的 bug 或某些临时的故障。
表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入 Retry-After 首部字段再返回给客户端。
HTTP 报文结构
大家请仔细看看上面示例中,各个组成部分对应的内容。 接着,我们来看看报文和实体的概念。如果把 HTTP 报文想象成因特网货运系统中的箱子,那么 HTTP 实体就是报文中实际的货物。
我们可以看到,上面示例右图中深红色框的内容就是报文的实体部分,而蓝色框的两部分内容分别就是实体首部和实体主体。而左图中粉红框内容就是报文主体。 通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异。
内容编码类型:
编码方式 描述 gzip 表明实体采用 GNU zip 编码 compress 表明实体采用 Unix 的文件压缩程序 deflate 表明实体采用 zlib 的格式压缩的 identity 表明没有对实体进行编码,当没有 Content-Encoding 首部字段时,默认采用此编码方式
内容编码是对报文的主体进行的可逆变换,是和内容的具体格式细节紧密相关的。 传输编码也是作用在实体主体上的可逆变换,但使用它们是由于架构方面的原因,同内容的格式无关。使用传输编码是为了改变报文中的数据在网络上传输的方式。
内容编码和传输编码的对比
分块编码把报文分割成若干已知大小的块。块之间是紧挨着发送的,这样就不需要在发送之前知道整个报文的大小了。分块编码是一种传输编码,是报文的属性。
分块编码与持久连接 若客户端与服务器端之间不是持久连接,客户端就不需要知道它在读取的主体的长度,而只需要读取到服务器关闭主体连接为止。 当使用持久连接时,在服务器写主体之前,必须知道它的大小并在 Content-Length 首部中发送。如果服务器动态创建内容,就可能在发送之前无法知道主体的长度。 分块编码为这种困难提供了解决方案,只要允许服务器把主体分块发送,说明每块的大小就可以了。因为主体是动态创建的,服务器可以缓冲它的一部分,发送其大小和相应的块,然后在主体发送完之前重复这个过程。服务器可以用大小为 0 的块作为主体结束的信号,这样就可以继续保持连接,为下一个响应做准备。 来看看一个分块编码的报文示例:
分块编码的报文
MIME 中的 multipart(多部分)电子邮件报文中包含多个报文,它们合在一起作为单一的复杂报文发送。每一部分都是独立的,有各自的描述其内容的集,不同部分之间用分界字符串连接在一起。 相应得,HTTP 协议中也采纳了多部分对象集合,发送的一份报文主体内可包含多种类型实体。 多部分对象集合包含的对象如下:
假设你正在下载一个很大的文件,已经下了四分之三,忽然网络中断了,那下载就必须重头再来一遍。为了解决这个问题,需要一种可恢复的机制,即能从之前下载中断处恢复下载。要实现该功能,这就要用到范围请求。 有了范围请求, HTTP 客户端可以通过请求曾获取失败的实体的一个范围(或者说一部分),来恢复下载该实体。当然这有一个前提,那就是从客户端上一次请求该实体到这一次发出范围请求的时间段内,该对象没有改变过。例如:
GET /bigfile.html HTTP/1.1
Host: www.sample.com
Range: bytes=20224-
···
实体范围请求示例
上面示例中,客户端请求的是文档开头20224字节之后的部分。
HTTP 通信时,除客户端和服务器外,还有一些用于协助通信的应用程序。如下列出比较重要的几个:代理、缓存、网关、隧道、Agent 代理。
代理
HTTP 代理服务器是 Web 安全、应用集成以及性能优化的重要组成模块。代理位于客户端和服务器端之间,接收客户端所有的 HTTP 请求,并将这些请求转发给服务器(可能会对请求进行修改之后再进行转发)。对用户来说,这些应用程序就是一个代理,代表用户访问服务器。 出于安全考虑,通常会将代理作为转发所有 Web 流量的可信任中间节点使用。代理还可以对请求和响应进行过滤,安全上网或绿色上网。
浏览器第一次请求:
浏览器第一次请求
浏览器再次请求:
浏览器再次请求
Web 缓存或代理缓存是一种特殊的 HTTP 代理服务器,可以将经过代理传输的常用文档复制保存起来。下一个请求同一文档的客户端就可以享受缓存的私有副本所提供的服务了。客户端从附近的缓存下载文档会比从远程 Web 服务器下载快得多。
HTTP / FTP 网关
网关是一种特殊的服务器,作为其他服务器的中间实体使用。通常用于将 HTTP 流量转换成其他的协议。网关接收请求时就好像自己是资源的源服务器一样。客户端可能并不知道自己正在跟一个网关进行通信。
HTTP/SSL 隧道
隧道是会在建立起来之后,就会在两条连接之间对原始数据进行盲转发的 HTTP 应用程序。HTTP 隧道通常用来在一条或多条 HTTP 连接上转发非 HTTP 数据,转发时不会窥探数据。 HTTP 隧道的一种常见用途就是通过 HTTP 连接承载加密的安全套接字层(SSL)流量,这样 SSL 流量就可以穿过只允许 Web 流量通过的防火墙了。
自动搜索引擎“网络蜘蛛”
Agent 代理是代表用户发起 HTTP 请求的客户端应用程序。所有发布 Web 请求的应用程序都是 HTTP Agent 代理。
原文链接:https://www.jianshu.com/p/6e9e4156ece3
TTP(Hypertext Transfer Protocol,超文本传输协议)是互联网中使用最广泛的通信协议之一,它定义了客户端与服务器之间的通信规则。无论是浏览网页、调用 API、下载文件,还是进行各种在线交互,HTTP 都是不可或缺的基础协议。HTTP 协议基于请求-响应模型工作,其中客户端发出请求,服务器返回响应。HTTP 请求方法定义了客户端希望执行的操作类型,每种请求方法都有特定的用途和行为。
在 HTTP/1.1 中,标准定义了多种请求方法,每种方法适用于不同的场景。本文将详细介绍九种 HTTP 请求方法:GET、POST、PUT、DELETE、PATCH、HEAD、CONNECT、OPTIONS 和 TRACE。这些方法在 Web 开发和 API 设计中扮演着重要角色。通过理解这些请求方法的功能和使用场景,开发者可以更好地设计和优化网络应用程序。
GET 方法是 HTTP 中最常用的请求方法之一,几乎在所有的 Web 应用中都能看到它的身影。GET 请求的主要作用是从服务器获取资源,例如网页、图片、视频等。当用户在浏览器中输入一个 URL 并按下回车键时,浏览器便会向服务器发送一个 GET 请求,要求获取该 URL 对应的资源。服务器处理请求后,会将资源发送回客户端,通常是 HTML、CSS、JavaScript 文件或其他媒体内容。
GET 方法的主要作用是从服务器请求数据,而不会对服务器上的资源进行任何修改。换句话说,GET 请求是"无副作用"的,不会改变服务器的状态。GET 请求通常用于以下场景:
示例:
GET /index.html HTTP/1.1
Host: www.example.com
在上述示例中,客户端通过 GET 请求从服务器获取 index.html 文件。服务器在处理该请求后,会返回相应的 HTML 文件给客户端。
GET 请求广泛应用于 Web 开发中,尤其是在需要从服务器获取数据的场景中。例如:
示例:
GET /search?q=http GET method HTTP/1.1
Host: www.searchengine.com
示例:
GET /product/12345 HTTP/1.1
Host: www.onlinestore.com
GET 请求的一个重要特性是可以被缓存。浏览器或中间代理服务器可以缓存 GET 请求的响应,以减少重复请求服务器的次数,从而提高性能并降低带宽消耗。HTTP 协议中定义了多种缓存机制,例如 ETag、Last-Modified 等,它们用于标识资源的状态,判断资源是否已改变。
缓存示例:
GET /logo.png HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
如果服务器返回的 ETag 与缓存中的 ETag 匹配,浏览器将直接使用缓存中的资源,而不重新下载文件。这不仅节省了带宽,还加快了页面加载速度。
GET 请求中常见的一种形式是通过 URL 参数或查询字符串传递数据。查询字符串通常附加在 URL 的末尾,以 ? 开头,参数与值之间用 = 连接,多个参数之间用 & 分隔。
示例:
GET /search?q=HTTP+GET+method&sort=latest HTTP/1.1
Host: www.example.com
在上述请求中,查询字符串 q=HTTP+GET+method&sort=latest 包含了两个参数:q 和 sort,分别表示搜索关键词和排序方式。这种方式适合传递简单的键值对数据,但由于查询字符串会暴露在 URL 中,因此不适合传输敏感信息。
尽管 GET 请求广泛使用,但在安全性方面需要注意以下几点:
为了增强安全性,建议在传输敏感数据时使用 POST 方法,并通过 HTTPS 加密通信。
POST 方法用于向服务器发送数据,通常是为了提交表单、上传文件、或调用 API 接口以进行数据处理。与 GET 方法不同,POST 请求的数据不会附加在 URL 中,而是包含在请求体中。因此,POST 方法适合传输较大或敏感的数据。
POST 方法的典型使用场景包括:
示例:
POST /submit-form HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
username=johndoe&password=secret123
示例:
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
(binary file data)
------WebKitFormBoundary--
示例:
POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "johndoe@example.com",
"password": "secret123"
}
POST 请求是非幂等的,这意味着重复发送相同的 POST 请求可能会产生不同的结果。例如,重复提交订单或评论可能会导致服务器生成多个相同的记录。由于这一特性,开发者在设计 API 时通常需要考虑如何防止重复提交的问题,例如使用唯一性约束、token 验证等手段。
与 GET 请求相比,POST 请求在安全性方面有一些显著的优势:
尽管如此,POST 请求仍然需要配合 HTTPS 协议使用,以确保数据在传输过程中的安全性。使用 HTTPS 可以加密数据,防止在传输过程中被窃取或篡改。
PUT 方法通常用于更新服务器上的资源。与 POST 方法不同,PUT 请求是幂等的,意味着多次发送相同的 PUT 请求,服务器的资源状态不会变化。PUT 方法可以用于创建或更新资源,通常用于更新现有资源的数据。
PUT 方法的典型使用场景包括:
示例:
PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "newemail@example.com"
}
示例:
PUT /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: text/plain
Updated document content...
PUT 方法是幂等的,这意味着相同的 PUT 请求无论执行多少次,服务器上的资源状态应保持一致。例如,用户修改个人资料后,如果重复发送相同的 PUT 请求,服务器上该用户的资料应保持不变,而不会生成多个相同的记录。
PUT 请求通常用于更新现有资源,因此在安全性方面需要特别注意以下几点:
DELETE 方法用于删除服务器上的指定资源。在 RESTful API 设计中,DELETE 方法通常用于移除指定的资源对象或数据。例如,删除一篇文章、一条评论、或一个用户账户等。DELETE 方法的幂等性特性决定了无论同一个 DELETE 请求被执行多少次,服务器上的资源状态应保持一致,即资源被删除后,再次删除操作不会产生任何新的效果。
DELETE 方法的典型使用场景包括:
DELETE 方法是幂等的,这意味着相同的 DELETE 请求无论执行多少次,服务器上的资源状态应保持一致。例如,发送 DELETE 请求删除一篇文章,如果文章已经被删除,再次发送相同的 DELETE 请求不会导致新的变化,服务器应返回一个指示资源已不存在的响应。
DELETE 请求涉及到资源的删除操作,因此需要特别注意以下几个方面的安全性问题:
PATCH 方法用于对服务器上的资源进行部分更新。与 PUT 方法不同,PATCH 请求不需要包含完整的资源数据,而只需要传输需要更新的部分字段。因此,PATCH 方法非常适合用于需要频繁更新部分数据的场景。
PATCH 方法的典型使用场景包括:
示例:
PATCH /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"email": "newemail@example.com"
}
示例:
PATCH /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"title": "Updated Document Title"
}
PATCH 方法通常被认为是非幂等的,这意味着相同的 PATCH 请求被执行多次可能会产生不同的结果。例如,如果一个 PATCH 请求是对字符串数据进行追加操作,那么重复执行相同的请求将会导致字符串的内容被多次追加,产生不同的结果。
然而,也有特定情况下的 PATCH 请求是幂等的,例如只是对某个字段的值进行覆盖更新。在这种情况下,PATCH 请求的幂等性与 PUT 方法类似。
PATCH 请求主要用于部分更新,因此在安全性方面需注意以下几点:
HEAD 方法与 GET 方法非常相似,但它只请求资源的首部信息,而不包含资源的具体内容。HEAD 请求的响应中只有状态行和头部字段,不返回消息体。HEAD 方法通常用于在不下载资源的情况下获取资源的元数据,如检查资源是否存在、获取资源的大小或类型等。
HEAD 方法的典型使用场景包括:
示例:
HEAD /files/sample.pdf HTTP/1.1
Host: www.example.com
示例:
HEAD /api/documents/456 HTTP/1.1
Host: www.example.com
HEAD 方法的一个显著特点是它不会返回消息体,因此在获取资源元数据时,HEAD 请求比 GET 请求更加高效。此外,由于 HEAD 请求不会返回资源内容,它通常被用作缓存控制的手段。例如,通过 HEAD 请求检查资源的 Last-Modified 或 ETag 头部字段,客户端可以决定是否需要重新下载资源。
CONNECT 方法用于建立一个到服务器的隧道连接,通常用于 HTTP 与 HTTPS 的代理请求。CONNECT 请求会将客户端的连接转换为一个双向通信的通道,允许客户端与目标服务器之间传递任意数据而不受代理服务器的影响。最常见的应用场景是通过 HTTP 代理访问 HTTPS 站点。
CONNECT 方法的典型使用场景包括:
示例:
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com
当代理服务器收到这个请求后,会建立一个与目标服务器的 TCP 连接,并将后续的所有数据直接传递给目标服务器。这种方式允许客户端与目标服务器之间的通信保持安全性和私密性,因为代理服务器只负责传递数据,而不进行解析或修改。
由于 CONNECT 方法用于创建一个隧道连接,它能够有效地维护客户端与服务器之间的通信隐私。然而,CONNECT 方法也可能被滥用。例如,恶意用户可以利用 CONNECT 方法绕过防火墙或其他网络安全措施,进行未经授权的访问。因此,许多代理服务器在使用 CONNECT 方法时会对目标端口或目标域名进行限制,防止滥用。
OPTIONS 方法用于查询服务器支持的请求方法或特定资源所支持的功能。它通常用于检查服务器的能力,确定哪些请求方法可以被安全地执行在指定资源上。OPTIONS 请求的响应通常包括 Allow 头部字段,列出服务器支持的请求方法。
OPTIONS 方法的典型使用场景包括:
示例:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
响应示例:
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE
示例:
OPTIONS /documents/456 HTTP/1.1
Host: www.example.com
响应示例:
HTTP/1.1 200 OK
Allow: GET, POST, DELETE, OPTIONS
OPTIONS 方法广泛用于 CORS 机制中,以确保跨域请求的安全性和合规性。通过预检请求,服务器可以控制哪些外部来源和请求方法可以访问其资源,从而避免跨站请求伪造(CSRF)攻击。
此外,OPTIONS 方法也可以用于测试和诊断服务器的配置,帮助开发者或管理员了解服务器的请求处理能力。
TRACE 方法用于在服务器上发起一个回环测试,即服务器将收到的请求原样返回给客户端。TRACE 方法的主要用途是诊断或调试,帮助客户端检查请求在传输过程中是否被修改或损坏。
TRACE 请求的典型使用场景包括:
示例:
TRACE /api/resource HTTP/1.1
Host: www.example.com
响应示例:
HTTP/1.1 200 OK
Content-Type: message/http
TRACE /api/resource HTTP/1.1
Host: www.example.com
User-Agent: MyBrowser/1.0
由于 TRACE 方法会将请求的所有信息,包括可能包含的敏感数据,如 Cookies 或 Authorization 头部,返回给客户端,这可能导致信息泄露。攻击者可以利用 TRACE 方法实施跨站点跟踪攻击(Cross-Site Tracing,XST),获取用户的敏感信息。因此,许多现代的 Web 服务器默认禁用 TRACE 方法以防止潜在的安全风险。
CORS ( Cross Origin Resource Sharing,跨域资源共享)机制允许Web应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在API容器中(如XMLHttpRequest或Fetch )使用CORS,以降低跨域HTTP请求所带来的风险。
本节将介绍如何在Spring Boot应用中,实现跨域访问资源。
当一个资源从与该资源本身所在的服务器不同的域或端口请求一一个资源时, 资源会发起- - 个跨域HTTP请求。
比如,站点ht://example-a.com 的某HTML页面通过<img>的src请求htp://example-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表、图像和脚本等资源。
W3C制定了CORS的相关规范,见hts://ww.w3.org/TR/cors/。出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。例如,XMLHttpRequest 和Fetch遵循同源策略。因此,使用XMLHtpRequest或Fetch的Web应用程序只能将HTTP请求发送到其自己的域。为了改进Web应用程序,开发人员要求浏览器厂商允许跨域请求。
识别是否具有跨域行为,是由同源政策决定的。同源政策由Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。所谓“同源”, 指的是“三个相同”。
协议相同。
●域名相同。
● 端口相同。
举例来说,htp://example.com/page.html 这个网址,协议是htp://, 域名是www.example.com,端口是80 (默认端口可以省略)。它的同源情况如下。
http://example. com/other.html:同源。
● ht://www.example.com/other.html: 不同源,域名不同。
● htp://v2.example.com/other.html: 不同源,域名不同。
● htp://example.com:81/other.html: 不同源,端口不同。
在微服务的架构里面,由于每个服务都在其自身的源中运行,因此,很容易就会遇到来自多个来源的客户端Web应用程序来访问服务的问题(即跨域访问)。例如,- -个浏览器客户端从“客户”
微服务器访问“客户”,并从“订单”微服务器访问订单历史记录,这种做法在微服务领域非常普遍。
Spring MVC支持CORS的开箱即用的功能。主要有两种实现跨域访问的方式。
1.方法级别的跨域访问
Spring Boot提供了一种简单的声明式方法来实现跨域请求。以下示例显示如何使用@CrossOr-igin注解,来启用允许跨域访问某些接口。
import org. springf ramework. web. bind. annotation. CrossOrigin;
@CrossOrigin(origins="*", maxAge=3600) // 允许所有域名访问
@Controller
public class FileController {
//..
}
其中,origins="**意味着允许所有域名访问(当然,你也可以限定某个域名来访问)。maxAge=3600是指有效期为3600秒。
2.全局跨域访问
可以通过使用自定义的addCorsMappings(CorsRegistry)方法注册WebMvcConfigurer bean来定义全局CORS配置。用法如下。
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer () {
@Override
public void addCorsMappings (CorsRegistry registry){
registry. addMapping ("/api/**");
};
}}
消息通信是企业信息集成中非常重要的一种方式。
消息的通信一般是由消息队列系统( MessageQueuing System, MQ )或面向消息中间件( Message Oriented Middleware, MOM )来提供高效可靠的消息传递机制进行平台无关的数据交流,并可基于数据通信进行分布式系统的集成。通过提供消息传递和消息排队模型,可在分布环境下扩展进程间的通信,并支持多种通信协议、语言、应用程序、硬件和软件平台。
通过使用MQ或MOM,通信双方的程序(称其为消息客户程序)可以在不同的时间运行,程序不在网络.上直接通话,而是间接地将消息放入MQ或MOM服务器的消息队列中。因为程序间没有直接的联系,所以它们不必同时运行:消息放入适当的队列时,目标程序不需要正在运行;即使目标程序在运行,也不意味着要立即处理该消息。
消息客户程序之间通过将消息放入消息队列或从消息队列中取出消息来进行通信。客户程序不直接与其他程序通信,避免了网络通信的复杂性。消息队列和网络通信的维护工作由MQ或MOM完成。
常见的MQ或MOM产品有Java Message Service、 Apache ActiveMQ、Apache RocketMQ、RabbitMQ、Apache Kafka等。
对于Spring应用而言,Spring Boot针对Java Message Service、RabbitMQ、 Apache Kafka等提供了开箱即用的支持。
Java Message Service ( JMS ) API是- -个 Java面向消息中间件的API,用于两个或多个客户端之间发送消息。
JMS的目标包括:
●包含实现复杂企业应用所需要的功能特性;
●定义了企业消息概念和功能的一组通用集合;
●最小化企业消息产品的概念,以降低学习成本。
最大化消息应用的可移植性。
JMS支持企业消息产品提供以下两种主要的消息风格。
●点对点 (Point-to-Point, PTP )消息风格:允许一个客户端通过-一个叫“队列( queue)”的中间抽象发送一个消息给另- 一个客户端。发送消息的客户端将-一个消息发送 到指定的队列中,接收消息的客户端从这个队列中抽取消息。
●发布订阅( Publish/Subscribe, Pub/Sub )消息风格:允许-一个客户端通过-一个叫“主题( topic )”的中间抽象发送一个消息给多个客 户端。发送消息的客户端将一个消 息发布到指定的主题中,然后这个消息将被投递到所有订阅了这个主题的客户端。
在Spring Boot应用中使用JMS,通常需要以下几个步骤。
1.使用JNDI ConnectionFactory
在应用程序中,Spring Boot将尝试使用JNDI找到JMS ConnectionFactory。 默认情况下,将检查位置java:/JmsXA和java:/XAConnectionFactory。如果需要指定其他位置,可以使用spring.jms.jndi-name属性。
spring.jms.jndi-name=java:/MyConnectionFactory
2.发送消息
Spring的JmsTemplate是自动配置的,可以将其直接自动装配到自己的bean中。
import org. springf ramework. beans. factory . annotation. Autowired;
import org. spr ingframework. jms . core . JmsTemplate;
import org. spr ingframework. stereotype . Component;
@Component
public class MyBean
private final JmsTemplate jmsTemplate;
@Autowi red
public MyBean (JmsTemplate jmsTemplate) {
this. jmsTemplate=jmsTemplate;
3.接收消息
在JMS架构中,可以使用@JmsListener来注解任何bean,以创建侦听器端点。如果没有定义JmsListenerContainerFactory,则会自动配置默认值。如果定义了DestinationResolver 或Message-Converter bean,则它们将自动关联到默认工厂。
默认工厂是事务性的。如果在JtaTransactionManager 存在的基础架构中运行,则默认情况下将
与侦听器容器相关联。如果没有,sessionTransacted 标志将被启用。在后一种情况下, 可以通过在
侦听器方法(或其代理)上添加@Transactional来将本地数据存储事务关联到传入消息的处理。这
将确保在本地事务完成后确认传入的消息。这还包括发送在同-一个JMS会话上执行的响应消息。
以下案例在someQueue目标上创建一个 侦听器端点。
@Component
public class MyBean {
@JmsListener (destination="someQueue")
public void processMessage (String content) {
}
}
RabbitMQ是更高级别的消息中间件,实现了Advanced Message Queuing Protocol( AMQP )协议。
Spring AMQP项目将核心Spring 概念应用于基于AMQP的消息传递解决方案的开发。Spring Boot提供了几种通过RabbitMQ与AMQP协同工作的开箱即用的方式,包括spring-boot- sarter-amqp等各种Starter。
1.配置RabbitMQ
RabbitMQ的配置由外部配置属性spring.rabbitmq.*来控制。例如,可以在application.properties中声明以下部分。
spring. rabbi tmq. host=localhost
spring. rabbi tmq.port=5672
spring. rabbi tmq . username=admin
spring. rabbi tmq. password=secret
2.发送消息
Spring 的AmqpTemplate和AmqpAdmin是自动配置的,可以将它们直接自动装配到自己的bean中。
import org.spr ingframework. amgp . core . AmqpAdmin;
import org. spr ingf ramework. amqp. core . AmqpTemplate;
import org. springframework.beans. factory . annotation. Autowired;
import org. springframework. stereotype. Component;
@Component
public class MyBean
private final AmqpAdmin amqpAdmin;
private final AmqpTemplate amqpTemplate;
@Autowired
public MyBean (AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
this . amqpAdmin=amqpAdmin;
this . amqpTemplate=amqpTemplate;
}
}
3.接收消息
当Rabbit 的基础架构存在时,可以使用@RabbitListener来注解bean,以创建侦听器端点。如果没有定义RabbitListenerContainerFactory,则会自动配置默认的SimpleRabitListenerContainerFactory。可以使用spring.rabbitmq.listener.type属性切换到直接容器。如果MessageConverter或MessageRecoverer bean被定义,它们将自动关联到默认工厂。
以下示例是在someQueue队列上创建-一个侦听器端点。
@Component
public class MyBean
@RabbitListener (queues=" someQueue")
public void processMessage (String content) {
//...
}
}
下篇文章给大家介绍数据持文化和实现热插拨两部分内容,欢迎大家来学习!!
也感谢大家支持!!
*请认真填写需求信息,我们会在24小时内与您取得联系。