詳解HTTP請(qǐng)求與響應(yīng)基礎(chǔ)及實(shí)例
詳解HTTP請(qǐng)求與響應(yīng)基礎(chǔ)及實(shí)例
一、HTTP的請(qǐng)求與響應(yīng)
二、HttpServletRequest和HttpServletResponse對(duì)象獲取HTTP響應(yīng)和請(qǐng)求
一、HTTP的請(qǐng)求與響應(yīng)
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議。是客戶端和服務(wù)器端之間數(shù)據(jù)傳輸?shù)母袷揭?guī)范。
通常,由HTTP客戶端發(fā)起一個(gè)請(qǐng)求,服務(wù)端一旦收到請(qǐng)求,向客戶端返回一個(gè)相應(yīng)(一個(gè)請(qǐng)求的發(fā)出,有且只有一個(gè)響應(yīng))。
(一)HTTP請(qǐng)求
請(qǐng)求報(bào)文格式如下:
請(qǐng)求行 - 請(qǐng)求頭 - 實(shí)體內(nèi)容
例如:
GET /webDemo/Hellow HTTP/1.1 //請(qǐng)求行 Host: localhost:8080 //請(qǐng)求頭 Connection: keep-alive Accept: text/html Accept-Encoding: gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8 //空行 //實(shí)體內(nèi)容
1、請(qǐng)求行
請(qǐng)求行的格式為
GET /webDemo/Hellow HTTP/1.1
請(qǐng)求方式 請(qǐng)求資源 http協(xié)議版本
(1)請(qǐng)求方式
請(qǐng)求方法有:
1) GET 請(qǐng)求指定的頁(yè)面信息,并返回實(shí)體主體。
2) HEAD 類似于get請(qǐng)求,只不過(guò)返回的響應(yīng)中沒(méi)有具體的內(nèi)容,用于獲取報(bào)頭
3) POST 向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請(qǐng)求體中。POST請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改。
4) PUT 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。
5) DELETE 請(qǐng)求服務(wù)器刪除指定的頁(yè)面。
6) CONNECT HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。
7) OPTIONS 允許客戶端查看服務(wù)器的性能。
8) TRACE 回顯服務(wù)器收到的請(qǐng)求,主要用于測(cè)試或診斷。
常用的請(qǐng)求方式主要是GET和POST(通常用于表單的提交),瀏覽器直接訪問(wèn)的請(qǐng)求,默認(rèn)提交方式為GET。
GET方法
提交的表單數(shù)據(jù)會(huì)在請(qǐng)求行的URI的后面。(以問(wèn)號(hào)開(kāi)頭,跟隨者鍵值對(duì),以&連接)提交的數(shù)據(jù)大小有限制,不能超過(guò)1KB。不適合提交敏感數(shù)據(jù)。
POST方法
表單提交的數(shù)據(jù)會(huì)包含在實(shí)體內(nèi)容當(dāng)中。
(2)請(qǐng)求資源
該請(qǐng)求資源為Request-URI是一個(gè)統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier)是一個(gè)用于標(biāo)識(shí)某一互聯(lián)網(wǎng)資源名稱的字符串。(本地,局域,互聯(lián)網(wǎng))
(3)HTTP協(xié)議版本
http 1.0:當(dāng)瀏覽器客戶端與服務(wù)器端建立連接后,發(fā)送一次請(qǐng)求后,就關(guān)閉連接
http 1.1:當(dāng)瀏覽器客戶端與服務(wù)器端建立連接后,可以在一次連接后,發(fā)送多次請(qǐng)求
2、請(qǐng)求頭
常見(jiàn)的請(qǐng)求行:
Accept:text/html,image/*
請(qǐng)求報(bào)頭域用于指定客戶端接受哪些類型的信息
Accept-Charset: ISO-8859-1
求資源主機(jī)接受的編碼格式
Accept-Encoding: gzip,compress
求資源主機(jī)接受的數(shù)據(jù)壓縮格式
Accept-Language: en-us,zh-
求資源主機(jī)接受的語(yǔ)言
Host: localhost:8080
(必須的)主要用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),它通常從HTTP URL中提取出來(lái)的
User-Agent:
求資源主機(jī)瀏覽器類型
Connection:
求資源主機(jī)跟服務(wù)器連接狀態(tài)
Connection: close 會(huì)發(fā)送請(qǐng)求后,自動(dòng)斷開(kāi)連接
Connection: Keep-Alive 會(huì)發(fā)送請(qǐng)求后,依然保持連接
Date
求資源主機(jī)發(fā)出請(qǐng)求的時(shí)間
(二)HTTP響應(yīng)
應(yīng)答報(bào)文格式如下:
響應(yīng)行 - 響應(yīng)頭 - 實(shí)體內(nèi)容
HTTP/1.1 200 OK //響應(yīng)行 Server: Apache-Coyote/1.1 //相應(yīng)頭 Content-Length: 0 Date: Thu, 18 May 2017 13:21:23 GMT //空行 //實(shí)體內(nèi)容
HTTP響應(yīng)與請(qǐng)求類似,主要了解的是其響應(yīng)行的狀態(tài)代碼。
狀態(tài)碼:
100-199 表示成功接收請(qǐng)求,要求客戶端繼續(xù)提交下一次請(qǐng)求才能完成整個(gè)處理過(guò)程
200-299 表示成功接收請(qǐng)求并已完成真?zhèn)€處理過(guò)程,常用200
300-399 為完成請(qǐng)求,客戶需進(jìn)一步細(xì)化請(qǐng)求
400-499 客戶端的請(qǐng)求有錯(cuò)誤,常用404
500-599 服務(wù)器出現(xiàn)錯(cuò)誤,常用500
常見(jiàn)的狀態(tài)碼:
200 表示請(qǐng)求處理完成并完美返回
302 表示請(qǐng)求需要進(jìn)一細(xì)化
404 表示客戶端訪問(wèn)的資源找不到
500 表示服務(wù)端出現(xiàn)問(wèn)題
二、HttpServletRequest和HttpServletResponse對(duì)象獲取HTTP響應(yīng)和請(qǐng)求
(一)HttpServletRequest
//HttpServletRequest對(duì)象的常見(jiàn)方法 //請(qǐng)求行: request.getMethod(); //獲取請(qǐng)求的提交方式 request.getRequestURI(); //獲取請(qǐng)求的URI request.getProtocol(); //獲取請(qǐng)求的協(xié)議 //請(qǐng)求頭: request.getHeader(); //獲取請(qǐng)求頭的強(qiáng)求值 request.getHeaderName(); //獲取請(qǐng)求頭的所有名稱 //實(shí)體內(nèi)容: request.getInputStream(); //獲取實(shí)體內(nèi)容的輸入流
例如,我們可以搭建一個(gè)tomcat servlet服務(wù)端,來(lái)獲取用客戶端的請(qǐng)求信息。
package sun; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Hellow */ @WebServlet("/Hellow") public class GetRequestInfo extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //創(chuàng)建一個(gè)字符串來(lái)存儲(chǔ)請(qǐng)求信息 StringBuffer req = new StringBuffer(); //獲取請(qǐng)求行 //獲取請(qǐng)求方法,URI,HTTP版本 req.append(request.getMethod()+" "+request.getRequestURI()+" "+request.getProtocol()+"\n"); //獲取請(qǐng)求頭 //獲取所有請(qǐng)求頭 Enumeration<?> headerName = request.getHeaderNames(); while(headerName.hasMoreElements()){ String header= (String)headerName.nextElement(); req.append(header+": "); //獲取指定請(qǐng)求頭的值 Enumeration<?> headerValue = request.getHeaders(header); while(headerValue.hasMoreElements()){ req.append((String)headerValue.nextElement()+";"); } req.append("\n"); } req.append("\n"); //獲取實(shí)體內(nèi)容 InputStream input = request.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len=input.read(buffer))!=-1){ String str = new String(buffer,0,len); req.append(str); } //輸出請(qǐng)求信息 System.out.println(req); } }
(二)HttpServletResponse
通過(guò)例子,來(lái)看通過(guò)修改響應(yīng)信息來(lái)實(shí)現(xiàn)一些業(yè)務(wù)邏輯。
package sun; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Response */ @WebServlet("/Response") public class ModifyResponseInfo extends HttpServlet { /** * Description: * 通過(guò)HttpServletResponse對(duì)象,改變響應(yīng)信息 * */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1、修改響應(yīng)行 resp.setStatus(404); //resp.sendError(404); //2、修改響應(yīng)頭 resp.setHeader("Server","JBoss"); //3、修改實(shí)體內(nèi)容 //發(fā)送字符類型的實(shí)體內(nèi)容 resp.getWriter().write("response"); //發(fā)送字節(jié)類型的實(shí)體內(nèi)容 resp.getOutputStream().write("response".getBytes()); //4、通過(guò)修改響應(yīng)頭,來(lái)請(qǐng)求重定向 //發(fā)送要給302狀態(tài)碼,location的響應(yīng)頭 /* 當(dāng)瀏覽器認(rèn)識(shí)到302狀態(tài)碼的時(shí)候,會(huì)再次自動(dòng)向服務(wù)器發(fā)出一個(gè)請(qǐng)求,請(qǐng)求的地址就是location的value值 請(qǐng)求重定向,一共向服務(wù)器發(fā)出2次請(qǐng)求 */ resp.setStatus(302); resp.setHeader("location","/webDemo/index.html"); //也可以直接調(diào)用sendRedirect方法直接重定向 //resp.sendRedirect("/webDemo/adv.html"); //5、通過(guò)修改響應(yīng)頭,來(lái)實(shí)現(xiàn)定時(shí)刷新頁(yè)面 //一秒后刷新頁(yè)面 resp.setHeader("refresh","1"); //也可以定時(shí)重定向頁(yè)面 //resp.setHeader("refresh","1;url=/webDemo/index.html"); //6、通過(guò)修改響應(yīng)頭,來(lái)修改服務(wù)端和客戶端的傳輸?shù)臄?shù)據(jù)類型 //resp.setHeader("content-type","text/html") //也可以直接調(diào)用setContentType方法直接設(shè)置 //在web.xml文件中找到對(duì)應(yīng)的數(shù)據(jù)類型寫(xiě)法 resp.setContentType("text/html"); } }
(三)獲取請(qǐng)求參數(shù)
由于GET和POST提交參數(shù)的位置不同(POST方法: 表單提交的數(shù)據(jù)會(huì)包含在實(shí)體內(nèi)容當(dāng)中;GET方法: 提交的表單數(shù)據(jù)會(huì)在請(qǐng)求行的URI的后面。),因此GET和POST方法獲取請(qǐng)求參數(shù)的方法也不樣。
//獲取GET方式參數(shù): request.getQueryString(); //獲取POST方式參數(shù): request.getInputStream();
但是這樣獲得的參數(shù),需要進(jìn)行字符串的拆分以后才能使用。因此,Tomcat自動(dòng)將GET和POST的請(qǐng)求參數(shù)封裝在HttpServletRequest對(duì)象當(dāng)中??梢哉{(diào)用以下方法獲得:
//根據(jù)指定名字來(lái)獲取參數(shù)值 request.getParameter("name"); request.getParameter("password"); //獲取所有參數(shù)名字 Enumeration<String> params = request.getParameterNames(); while(params.hasMoreElements()){ String param = params.nextElement(); String value = request.getParameter(param); }
(四)編碼問(wèn)題
服務(wù)端和客戶端可能存在著編碼問(wèn)題,當(dāng)服務(wù)端和客戶端的編碼不同時(shí),傳輸?shù)臄?shù)據(jù)就有可能因?yàn)榫幋a問(wèn)題而導(dǎo)致亂碼。
1、手動(dòng)解碼
在獲取的每個(gè)數(shù)據(jù)進(jìn)行手工再次編碼,這里是必須知道服務(wù)端的編碼方式和客戶端的編碼方法。
name = new String(name.getBytes("iso-8859-1"),"utf-8");
2、設(shè)置參數(shù)查詢碼表
在獲取數(shù)據(jù)之前,調(diào)用setCharacherEncoding方法設(shè)置指定編碼格式。
該方法,只能對(duì)請(qǐng)求實(shí)體內(nèi)容的編碼起作用,所以只能對(duì)POST提交參數(shù)起作用。
request.setCharacherEncoding(“utf-8”);
3、修改服務(wù)器的配置文件
比如,tomcat服務(wù)器當(dāng)中,修改server.xml配置文件
<!-- A "Connector" represents an endpoint by which requests are received and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html (blocking & non-blocking) Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 --> <!--在這里,加上屬性URIEncoding,及指定編碼值--> <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
以上就是HTTP請(qǐng)求與響應(yīng)基礎(chǔ)的詳細(xì)介紹,如有疑問(wèn)請(qǐng)大家留言!感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
SpringBoot集成minio實(shí)現(xiàn)文件上傳和刪除功能
這篇文章主要介紹了SpringBoot集成minio實(shí)現(xiàn)文件上傳和刪除功能,詳細(xì)介紹每個(gè)功能的實(shí)現(xiàn)步驟和代碼示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11JAXB簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了JAXB簡(jiǎn)介的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08java使用ArrayList實(shí)現(xiàn)斗地主(無(wú)序版)
這篇文章主要為大家詳細(xì)介紹了java使用ArrayList實(shí)現(xiàn)斗地主,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03SpringCloud超詳細(xì)講解Feign聲明式服務(wù)調(diào)用
Feign可以把Rest的請(qǐng)求進(jìn)行隱藏,偽裝成類似Spring?MVC的Controller一樣。不用再自己拼接url,拼接參數(shù)等等操作,一切都交給Feign去做2022-06-06zookeeper實(shí)戰(zhàn)之實(shí)現(xiàn)分布式鎖的方法
Zookeeper實(shí)現(xiàn)分布式鎖比Redis簡(jiǎn)單,Zookeeper有一個(gè)特性,多個(gè)線程在Zookeeper里創(chuàng)建同一個(gè)節(jié)點(diǎn)時(shí),只有一個(gè)線程執(zhí)行成功,Zookeeper主要是利用臨時(shí)有序節(jié)點(diǎn)這一特性實(shí)現(xiàn)分布式鎖,感興趣的朋友跟隨小編一起學(xué)習(xí)吧2022-11-11springboot?vue項(xiàng)目管理后端實(shí)現(xiàn)接口新增
這篇文章主要為大家介紹了springboot?vue項(xiàng)目管理后端實(shí)現(xiàn)接口新增,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05Springboot?如何使用BindingResult校驗(yàn)參數(shù)
這篇文章主要介紹了Springboot?如何使用BindingResult校驗(yàn)參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01SpringMVC日期類型接收空值異常問(wèn)題解決方法
這篇文章主要介紹了SpringMVC日期類型接收空值異常問(wèn)題解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Gradle的SpringBoot項(xiàng)目構(gòu)建圖解
這篇文章主要介紹了Gradle的SpringBoot項(xiàng)目構(gòu)建圖解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01