欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java創(chuàng)建非阻塞的HTTP服務(wù)器的實現(xiàn)

 更新時間:2024年04月10日 10:31:11   作者:布道師小羊  
本文主要介紹了Java創(chuàng)建非阻塞的HTTP服務(wù)器的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

HTTP(Hypertext Transfer Protocol,超級文本傳輸協(xié)議)是網(wǎng)絡(luò)應(yīng)用層的協(xié)議,建立在TCP/IP基礎(chǔ)上。HTTP使用可靠的TCP連接,默認(rèn)端口是80端口。HTTP的第1個版本是HTTP/0.9,后來發(fā)展到了HTTP/1,現(xiàn)在最新的版本是HTTP/2。值得注意的是,在目前的實際運用中,HTTP/2并沒有完全取代HTTP/1,而是這兩種協(xié)議在網(wǎng)絡(luò)上并存,也就是說,許多Web服務(wù)器和瀏覽器之間既可以通過HTTP/1通信,也可以通過HTTP/2通信。

HTTP/1.1對應(yīng)的RFC文檔為RFC2616,它對HTTP/1.1做了詳細(xì)的闡述。HTTP/2對應(yīng)的RFC文檔為RFC7540,它對HTTP/2協(xié)議做了詳細(xì)的闡述。

HTTP基于客戶/服務(wù)器模式,客戶端主動發(fā)出HTTP請求,服務(wù)器接收HTTP請求,返回HTTP響應(yīng)結(jié)果。HTTP對HTTP請求以及響應(yīng)的格式做了明確的規(guī)定。

1、Htpp簡介

當(dāng)用戶打開瀏覽器,輸入一個URL地址,就能接收到遠(yuǎn)程HTTP服務(wù)器發(fā)送過來的網(wǎng)頁。瀏覽器就是最常見的HTTP客戶程序。如下圖所示,HTTP客戶程序必須先發(fā)出一個HTTP請求,然后才能接收到來自HTTP服務(wù)器的響應(yīng)。

在這里插入圖片描述

HTTP客戶程序和HTTP服務(wù)器分別由不同的軟件開發(fā)商提供,它們都可以用任意的編程語言編寫。用VC編寫的HTTP客戶程序能否與用Java編寫的HTTP服務(wù)器順利通信呢?答案是肯定的。HTTP嚴(yán)格規(guī)定了HTTP請求和HTTP響應(yīng)的數(shù)據(jù)格式,只要HTTP服務(wù)器與客戶程序都遵守HTTP,就能彼此看得懂對方發(fā)送的消息。

1.1、HTTP請求格式

HTTP規(guī)定,HTTP請求由3部分構(gòu)成,分別是:

  • 請求方法、URI、HTTP的版本
  • 請求頭(Request Header)
  • 請求正文(Request Content)

下面是一個HTTP請求的例子:

在這里插入圖片描述

1.請求方式、URI、HTTP的版本

HTTP請求的第1行包括請求方式、URI和協(xié)議版本這3項內(nèi)容,以空格分開:

在這里插入圖片描述

在以上代碼中,“POST” 表示請求方式,“/hello”表示URI,“HTTP/1.1”表示HTTP的版本。

根據(jù)HTTP,HTTP請求可以使用多種請求方式,主要包括以下幾種:

  • GET:這種請求方式最為常見,客戶程序通過這種請求方式訪問服務(wù)器上的一個文檔,服務(wù)器把文檔發(fā)送給客戶程序。
  • POST:客戶程序可通過這種方式發(fā)送大量信息給服務(wù)器。在HTTP請求中除了包含要訪問的文檔的URI,還包括大量的請求正文,這些請求正文中通常會包含大量HTML表單數(shù)據(jù)。
  • HEAD:客戶程序和服務(wù)器之間交流一些內(nèi)部數(shù)據(jù),服務(wù)器不會返回具體的文檔。當(dāng)使用GET和POST方法時,服務(wù)器最后都將特定的文檔返回給客戶程序。而HEAD請求方式則不同,它僅僅交流一些內(nèi)部數(shù)據(jù),這些數(shù)據(jù)不會影響用戶瀏覽網(wǎng)頁的過程,可以說對用戶是透明的。HEAD請求方式通常不單獨使用,而是為其他請求方式起輔助作用。一些搜索引擎使用HEAD請求方式來獲得網(wǎng)頁的標(biāo)志信息,還有一些HTTP服務(wù)器在進行安全認(rèn)證時,用這個方式來傳遞認(rèn)證信息。
  • PUT:客戶程序通過這種方式把文檔上傳給服務(wù)器。
  • DELETE:客戶程序通過這種方式來刪除遠(yuǎn)程服務(wù)器上的某個文檔??蛻舫绦蚩梢岳肞UT和DELETE請求方式來管理遠(yuǎn)程服務(wù)器上的文檔。

GET和POST請求方式最常用,而PUT和DELETE請求方式并不常用,因而不少HTTP服務(wù)器并不支持PUT和DELETE請求方式。

統(tǒng)一資源定位符(Universal Resource Identifier,URI)用于標(biāo)識要訪問的網(wǎng)絡(luò)資源。在HTTP請求中,通常只要給出相對于服務(wù)器的根目錄的相對目錄即可,因此以“/”開頭。

HTTP請求的第1行的最后一部分內(nèi)容為客戶程序使用的HTTP的版本。

2.請求頭(Request Header)

請求頭包含許多有關(guān)客戶端環(huán)境和請求正文的有用信息。例如,請求頭可以聲明瀏覽器的類型、所用的語言、請求正文的類型,以及請求正文的長度等。

在這里插入圖片描述

3.請求正文(Request Content)

HTTP規(guī)定,請求頭和請求正文之間必須以空行分割(即只有CRLF符號的行),這個空行非常重要,它表示請求頭已經(jīng)結(jié)束,接下來是請求正文。請求正文中可以包含客戶以POST方式提交的表單數(shù)據(jù)。

在這里插入圖片描述

在以上HTTP請求例子中,請求正文只有一行內(nèi)容。在實際應(yīng)用中,HTTP請求的正文可以包含更多的內(nèi)容。

下面是一個簡單的HTTP客戶程序,它發(fā)送的HTTP請求信息就嚴(yán)格遵守上述規(guī)范。

在這里插入圖片描述

1.2、HTTP響應(yīng)格式

和HTTP請求相似,HTTP響應(yīng)也由3部分構(gòu)成,分別是:

  • HTTP的版本、狀態(tài)代碼、描述
  • 響應(yīng)頭(Response Header)
  • 響應(yīng)正文(Response Content)

下面是一個HTTP響應(yīng)的例子:

在這里插入圖片描述

1.HTTP的版本、狀態(tài)代碼、描述

HTTP響應(yīng)的第1行包括服務(wù)器使用的HTTP的版本、狀態(tài)代碼,以及對狀態(tài)代碼的描述,這3項內(nèi)容之間以空格分割。在本例中,使用HTTP1.1,狀態(tài)代碼為200,該狀態(tài)代碼表示服務(wù)器已經(jīng)成功地處理了客戶端發(fā)出的請求。

在這里插入圖片描述

狀態(tài)代碼是一個3位整數(shù),以1、2、3、4或5開頭:

  • 1xx:信息提示,表示臨時的響應(yīng)。
  • 2xx:響應(yīng)成功,表明服務(wù)器成功的接收了客戶端請求。
  • 3xx:重定向。
  • 4xx:客戶端錯誤,表明客戶端可能有問題。
  • 5xx:服務(wù)器錯誤,表明服務(wù)器由于遇到某種錯誤而不能響應(yīng)客戶請求。

以下是一些常見的狀態(tài)代碼:

  • 200:響應(yīng)成功。
  • 400:錯誤的請求。客戶發(fā)送的HTTP請求不正確。
  • 404:文件不存在。在服務(wù)器上沒有客戶要求訪問的文檔。
  • 405:服務(wù)器不支持客戶的請求方式。
  • 500:服務(wù)器內(nèi)部錯誤。

2.響應(yīng)頭(Response Header)

響應(yīng)頭也和請求頭一樣包含許多有用的信息,例如服務(wù)器類型、正文類型和正文長度等。

在這里插入圖片描述

3.響應(yīng)正文(Response Content)

響應(yīng)正文就是服務(wù)器返回的具體的文檔,最常見的是HTML網(wǎng)頁。

在這里插入圖片描述

HTTP請求頭與請求正文之間必須用空行分割,同樣,HTTP響應(yīng)頭與響應(yīng)正文之間也必須用空行分隔。

2、創(chuàng)建非阻塞的HTTP服務(wù)器

HTTP服務(wù)器的主要任務(wù)就是接收HTTP請求,然后發(fā)送HTTP響應(yīng)。下圖是我們要介紹的非阻塞的HTTP服務(wù)器范例的模型。

在這里插入圖片描述

在這個對象模型中,HttpServer類是服務(wù)器主程序,由它啟動服務(wù)器。AcceptHandler負(fù)責(zé)接收客戶連接,RequestHandler負(fù)責(zé)接收客戶的HTTP請求,對其解析,然后生成相應(yīng)的HTTP響應(yīng),再把它發(fā)送給客戶。Request類表示HTTP請求,Response類表示HTTP響應(yīng),Content類表示HTTP響應(yīng)的正文。

2.1、服務(wù)器主程序:HttpServer類

HttpServer類是服務(wù)器的主程序,僅啟用了單個主線程,采用非阻塞模式來接收客戶連接,以及收發(fā)數(shù)據(jù)。下面是HttpServer類的源程序。

在這里插入圖片描述

在HttpServer類的service()方法中,當(dāng)ServerSocketChannel向Selector注冊接收連接就緒事件時,設(shè)置了一個AcceptHandler附件:

在這里插入圖片描述

AcceptHandler類的handle()方法負(fù)責(zé)處理接收連接就緒事件。當(dāng)某種事件發(fā)生時,HttpServer類的service()方法從SelectionKey中獲得Handler附件,然后調(diào)用它的handle()方法:

在這里插入圖片描述

2.2、具有自動增長的緩沖區(qū)的ChannelIO類

自定義的ChannelIO類對SocketChannel進行了包裝,增加了自動增長緩沖區(qū)容量的功能。當(dāng)調(diào)用socketChannel.read(ByteBuffer buffer)方法時,如果buffer已滿(即position=limit),那么即使通道中還有未接收的數(shù)據(jù),read方法也不會讀取任何數(shù)據(jù),而是直接返回0,表示讀到了零字節(jié)。

為了能讀取通道中的所有數(shù)據(jù),必須保證緩沖區(qū)的容量足夠大。在ChannelIO類中,有一個requestBuffer變量,它用來存放客戶的HTTP請求數(shù)據(jù),當(dāng)requestBuffer剩余容量已經(jīng)不足5%,并且還有HTTP請求數(shù)據(jù)未接收時,ChannelIO會自動擴充requestBuffer的容量,該功能由resizeRequestBuffer()方法完成。

下面是ChannelIO類的源程序,它的read()方法和write()方法利用SocketChannel來接收和發(fā)送數(shù)據(jù),并且它還提供了實用方法transferTo(),該方法能把文件中的數(shù)據(jù)發(fā)送到SocketChannel中。

在這里插入圖片描述

2.3、負(fù)責(zé)處理各種事件的Handler接口

Handler接口負(fù)責(zé)處理各種事件,它的定義如下:

在這里插入圖片描述

Handler接口有AcceptHandler和RequestHandler兩個實現(xiàn)類。AcceptHandler負(fù)責(zé)處理接收連接就緒事件,RequestHandler負(fù)責(zé)處理讀就緒和寫就緒事件。更確切地說,RequestHandler負(fù)責(zé)接收客戶的HTTP請求,以及發(fā)送HTTP響應(yīng)。

2.4、負(fù)責(zé)處理接收連接就緒事件的AcceptHandler類

AcceptHandler負(fù)責(zé)處理接收連接就緒事件。它獲得與客戶連接的SocketChannel,然后向Selector注冊讀就緒事件,并且創(chuàng)建了一個RequestHandler,把它作為SelectionKey的附件。當(dāng)讀就緒事件發(fā)生時,將由這個RequestHandler來處理該事件。

在這里插入圖片描述

在以上AcceptHandler的handle()方法中,還創(chuàng)建了一個ChannelIO,RequestHandler與它關(guān)聯(lián)。RequestHandler會利用ChannelIO來接收和發(fā)送數(shù)據(jù)。

2.5、負(fù)責(zé)接收HTTP請求和發(fā)送HTTP響應(yīng)的RequestHandler類

RequestHandler先通過ChannelIO來接收HTTP請求,當(dāng)接收到了HTTP請求的所有數(shù)據(jù)后,就對HTTP請求數(shù)據(jù)進行解析,創(chuàng)建相應(yīng)的Request對象,然后依據(jù)客戶的請求內(nèi)容,創(chuàng)建相應(yīng)的Response對象,最后發(fā)送Response對象中包含的HTTP響應(yīng)數(shù)據(jù)。為了簡化程序,RequestHandler僅僅支持GET和HEAD這兩種請求方式。

在這里插入圖片描述

2.6、代表HTTP請求的Request類

RequestHandler通過ChannelIO讀取HTTP請求數(shù)據(jù)時,這些數(shù)據(jù)被放在requestByteBuffer中。當(dāng)HTTP請求的所有數(shù)據(jù)接收完畢,就要對requestByteBuffer中的數(shù)據(jù)進行解析,然后創(chuàng)建相應(yīng)的Request對象。Request對象就表示特定的HTTP請求。

本范例僅支持GET和HEAD請求方式,在這兩種方式下,HTTP請求沒有正文部分,并且以“\r\n\r\n”結(jié)尾。Request類有3個成員變量:action、uri和version,它們分別表示HTTP請求中的請求方式、URI和HTTP的版本。下面是Request類的源程序。

在這里插入圖片描述

2.7、代表HTTP響應(yīng)的Response類

Response類表示HTTP響應(yīng)。它有3個成員變量:code、headerBuffer和content,它們分別表示HTTP響應(yīng)中的狀態(tài)代碼、響應(yīng)頭和正文。Response類的prepare()方法負(fù)責(zé)準(zhǔn)備HTTP響應(yīng)的響應(yīng)頭和正文內(nèi)容,send()方法負(fù)責(zé)發(fā)送HTTP響應(yīng)的所有數(shù)據(jù)。下面是Response類的源程序:

在這里插入圖片描述

2.8、代表響應(yīng)正文的Content接口及其實現(xiàn)類

Response類有一個成員變量content,表示響應(yīng)正文,它被定義為Content類型。

在這里插入圖片描述

Content接口表示響應(yīng)正文,它的定義如下:

在這里插入圖片描述

Content接口繼承了Sendable接口,Sendable接口表示服務(wù)器端可發(fā)送給客戶的內(nèi)容,它的定義如下:

在這里插入圖片描述

Content接口有StringContent和FileContent兩個實現(xiàn)類。StringContent表示字符串形式的正文,F(xiàn)ileContent表示文件形式的正文。例如在RequestHandler類的build()方法中,如果HTTP請求方式不是GET和HEAD,就創(chuàng)建一個包含StringContent的Response對象,否則就創(chuàng)建一個包含F(xiàn)ileContent的Response對象。

在這里插入圖片描述

下面主要介紹FileContent類的實現(xiàn)。FileContent類有一個成員變量fileChannel,它表示讀文件的通道。FileContent類的send()方法把fileChannel中的數(shù)據(jù)發(fā)送到ChannelIO的SocketChannel中,如果文件中的所有數(shù)據(jù)發(fā)送完畢,send()方法就返回false。下面是FileContent類的源程序。

在這里插入圖片描述

2.9、運行HTTP服務(wù)器

運行命令“java HttpServer”,就啟動了HTTP服務(wù)器。在本范例的root目錄下存放了各種供瀏覽器訪問的文檔,比如login.htm、hello.htm和data.rar文件等。打開IE瀏覽器,輸入URL:http://localhost/login.htm或者h(yuǎn)ttp://localhost/data.rar,就能接收到服務(wù)器發(fā)送過來的相應(yīng)文檔。如果瀏覽器按照POST方式訪問hello.htm,服務(wù)器就會返回HTTP405錯誤,因為本服務(wù)器不支持POST方式。

3、總結(jié)

HTTP是目前使用非常廣泛的應(yīng)用層協(xié)議,它規(guī)定了在網(wǎng)絡(luò)上傳輸文檔(主要是HTML格式的網(wǎng)頁)的規(guī)則。HTTP的客戶程序主要是瀏覽器。瀏覽器訪問一個遠(yuǎn)程HTTP服務(wù)器上的網(wǎng)頁的步驟如下:

  • (1)建立與遠(yuǎn)程服務(wù)器的連接。
  • (2)發(fā)送HTTP請求。
  • (3)接收HTTP響應(yīng),斷開與遠(yuǎn)程服務(wù)器的連接。
  • (4)展示HTTP響應(yīng)中的網(wǎng)頁內(nèi)容。

HTTP服務(wù)器必須接收HTTP請求,對它進行解析,然后返回相應(yīng)的HTTP響應(yīng)結(jié)果。本章創(chuàng)建了一個非阻塞的HTTP服務(wù)器,它首先讀取HTTP請求,把它們存放在字節(jié)緩沖區(qū)內(nèi),當(dāng)緩沖區(qū)的容量不夠時,會擴充它的容量,以保證容納HTTP請求的所有數(shù)據(jù)。接著,程序把字節(jié)緩沖區(qū)內(nèi)的字節(jié)轉(zhuǎn)換為字符串,對其進行解析,獲得HTTP請求中的請求方式、URI和協(xié)議版本等信息,然后創(chuàng)建相應(yīng)的HTTP響應(yīng),把它發(fā)送給客戶程序。

到此這篇關(guān)于Java創(chuàng)建非阻塞的HTTP服務(wù)器的實現(xiàn)的文章就介紹到這了,更多相關(guān)Java 非阻塞HTTP服務(wù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java如何自定義List中的sort()排序,用于日期排序

    java如何自定義List中的sort()排序,用于日期排序

    這篇文章主要介紹了java如何自定義List中的sort()排序,用于日期排序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java實現(xiàn)解析.xlsb文件的示例代碼

    Java實現(xiàn)解析.xlsb文件的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)解析.xlsb文件的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的可以了解一下
    2023-01-01
  • 詳解基于Spring Cloud幾行配置完成單點登錄開發(fā)

    詳解基于Spring Cloud幾行配置完成單點登錄開發(fā)

    這篇文章主要介紹了詳解基于Spring Cloud幾行配置完成單點登錄開發(fā),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java?超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中的堆的應(yīng)用

    Java?超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中的堆的應(yīng)用

    堆首先是一個完全二叉樹,堆分為小根堆和大根堆。小根堆,所有結(jié)點的左右子節(jié)點都不小于根節(jié)點;大根堆,所有結(jié)點的左右子節(jié)點都不大于根節(jié)點。優(yōu)先級隊列(priorityQueue)底層就是一個小根堆
    2022-04-04
  • JDK13的新特性之AppCDS詳解

    JDK13的新特性之AppCDS詳解

    AppCDS的全稱是Application Class-Data Sharing。主要是用來在不同的JVM中共享Class-Data信息,從而提升應(yīng)用程序的啟動速度。這篇文章主要介紹了JDK13的新特性:AppCDS詳解,需要的朋友可以參考下
    2020-05-05
  • Spring Boot 參數(shù)校驗的具體實現(xiàn)方式

    Spring Boot 參數(shù)校驗的具體實現(xiàn)方式

    這篇文章主要介紹了Spring Boot 參數(shù)校驗的具體實現(xiàn)方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • Java基于JDK 1.8的LinkedList源碼詳析

    Java基于JDK 1.8的LinkedList源碼詳析

    這篇文章主要給大家介紹了關(guān)于Java基于JDK 1.8的LinkedList源碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Java中BigInteger類的使用方法詳解(全網(wǎng)最新)

    Java中BigInteger類的使用方法詳解(全網(wǎng)最新)

    這篇文章主要介紹了Java中BigInteger類的使用方法詳解,常用最全系列,本章作為筆記使用,內(nèi)容比較全面,但常用的只有:構(gòu)造函數(shù),基本運算以及compareTo(),intValue(),setBit(),testBit()方法,需要的朋友可以參考下
    2023-05-05
  • ssm框架controller層返回json格式數(shù)據(jù)到頁面的實現(xiàn)

    ssm框架controller層返回json格式數(shù)據(jù)到頁面的實現(xiàn)

    這篇文章主要介紹了ssm框架controller層返回json格式數(shù)據(jù)到頁面的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 常用Maven庫,鏡像庫及maven/gradle配置(小結(jié))

    常用Maven庫,鏡像庫及maven/gradle配置(小結(jié))

    這篇文章主要介紹了常用Maven庫,鏡像庫及maven/gradle配置(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論