亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談web服務(wù)器項(xiàng)目中request請(qǐng)求和response的相關(guān)響應(yīng)處理

 更新時(shí)間:2020年07月20日 15:57:49   作者:suwu150  
這篇文章主要介紹了淺談web服務(wù)器項(xiàng)目中request請(qǐng)求和response的相關(guān)響應(yīng)處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

  我們經(jīng)常使用別人的服務(wù)器進(jìn)行構(gòu)建網(wǎng)站,現(xiàn)在我們就自己來(lái)寫(xiě)一個(gè)自己的服務(wù)來(lái)使用。

準(zhǔn)備工作:下載所需的題材及文檔

注:完整項(xiàng)目下載

一、request請(qǐng)求獲取

 1、了解request請(qǐng)求

在寫(xiě)服務(wù)器之前,我們需要知道客戶(hù)端發(fā)送給我們哪些信息?以及要求我們返回哪些信息?經(jīng)過(guò)測(cè)試我們能夠知道用戶(hù)客戶(hù)端發(fā)送的信息有以下幾點(diǎn):

客戶(hù)端發(fā)送到服務(wù)器端的請(qǐng)求消息,我們稱(chēng)之為請(qǐng)求(request),其實(shí)就是一個(gè)按照http協(xié)議的規(guī)則拼接而成的字符串,Request請(qǐng)求消息包含三部分: 請(qǐng)求行 消息報(bào)頭 請(qǐng)求正文
        第一部 請(qǐng)求行
            格式:
            Method Request-URI HTTP-Version CRLF
             各部分分別為:
            Method表示請(qǐng)求方法;一般為GET或者POST ;Request-URI是一個(gè)統(tǒng)一資源標(biāo)識(shí)符; HTTP-Version表示請(qǐng)求的HTTP協(xié)議版本; CRLF表示回車(chē)和換行
            例如:
            GET /test.html HTTP/1.1  

        第二部 消息報(bào)頭 http header
            例如:
            GET /test.html HTTP/1.1
            Host: 127.0.0.1:9999
            User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
            Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            Accept-Language: zh-CN,en;q=0.8,zh;q=0.5,en-US;q=0.3
            Accept-Encoding: gzip, deflate
            Connection: keep-alive 

        第三部 請(qǐng)求正文 http body
            請(qǐng)求頭和請(qǐng)求正文之間是一個(gè)空行,這個(gè)行非常重要,它表示請(qǐng)求頭已經(jīng)結(jié)束,接下來(lái)的是請(qǐng)求正文。請(qǐng)求正文中可以包含客戶(hù)提交的字符串信息

        注意:在第二部分header和第三部分body之間有個(gè)空行,除非沒(méi)有請(qǐng)求正文(如果你想要親自看到效果,請(qǐng)參考:瀏覽器中GET和POST的區(qū)別),這是因?yàn)橛脩?hù)在瀏覽網(wǎng)頁(yè)時(shí)提交給服務(wù)器的信息是不同的

 2、實(shí)現(xiàn)

         經(jīng)過(guò)以上分析,我們就能夠清楚的知道,客戶(hù)端發(fā)送給服務(wù)器的請(qǐng)求,請(qǐng)求信息有使用的協(xié)議、請(qǐng)求的方法、請(qǐng)求的資源路徑、請(qǐng)求的消息報(bào)頭、判斷請(qǐng)求的內(nèi)容是否為靜態(tài)資源、判斷請(qǐng)求的內(nèi)容是否為動(dòng)態(tài)資源、判斷是否為空請(qǐng)求,為了使用的方便,我們需要將其封裝起來(lái),總不能使用一次讀取一次吧,這樣做實(shí)在是太浪費(fèi)系統(tǒng)資源與時(shí)間了,如下代碼,就是一個(gè)接口類(lèi),用于獲取客戶(hù)端發(fā)送過(guò)來(lái)的屬性

package com.sample.http;
import java.util.Map;
 // http協(xié)議的請(qǐng)求
public interface HttpRequest {
 //獲得請(qǐng)求的協(xié)議
 public String getProtocol();
 //獲得請(qǐng)求的方法
 public String getRequestMethod();
 //獲得請(qǐng)求的路徑
 public String getRequestPath();
 //獲得請(qǐng)求的消息報(bào)頭
 public Map<String,String> getRequestHeader();
 //根據(jù)參數(shù)的名字獲得請(qǐng)求帶過(guò)來(lái)的參數(shù)值
 public String getParameter(String parameterName);
 //判斷當(dāng)前請(qǐng)求的否是靜態(tài)資源
 public boolean isStaticResource();
 //判斷當(dāng)前請(qǐng)求的否是動(dòng)態(tài)資源
 public boolean isDynamicResource();
 //判斷當(dāng)前請(qǐng)求的否是為空請(qǐng)求(有些瀏覽器會(huì)自動(dòng)發(fā)送空請(qǐng)求)
 public boolean isNullRequest();
}

有了接口類(lèi)之后,我們就可以創(chuàng)建類(lèi)進(jìn)行實(shí)現(xiàn),下面就是實(shí)現(xiàn)類(lèi),用于對(duì)各個(gè)方法進(jìn)行處理:

package com.sample.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HttpRequestImpl implements HttpRequest{
	//客戶(hù)端的Socket
	private Socket s;
	private InputStream is=null;//輸入流
	private BufferedReader br=null;
	private HashMap<String,String> hmHeader=new HashMap<String,String>();//消息報(bào)頭
	private HashMap<String,String> hmparameters=new HashMap<String, String>();//參數(shù)集合
	private boolean isNullRequest=false;//是否為空請(qǐng)求,默認(rèn)false
	private String protocol=null;//請(qǐng)求協(xié)議
	private String requestMethod=null;//請(qǐng)求方法
	private String requestPath=null;//請(qǐng)求路徑
	public HttpRequestImpl(Socket s) {
		this.s=s;
		getInfos();//調(diào)用方法
	 }
	private void getInfos()//定義一個(gè)方法,用于處理獲取的客戶(hù)端信息
	{
		try {
			is=s.getInputStream();
			br=new BufferedReader(new InputStreamReader(is));
			//解析第一行
			String str;
			str=br.readLine();//readLine使用回車(chē)換行判斷一行是否結(jié)束
			if(str==null)
			{
				isNullRequest=true;
				return;
			}
			parseRequestMethodPathProtocol(str);//調(diào)用自己創(chuàng)建在本類(lèi)里邊的方法處理第一行信息,方法在后面
		//解析第二行---第八行
			String header=null;  
  //判斷是否結(jié)束,如果結(jié)束就退出,這里的判斷按較為饒人
  //首先應(yīng)該明確br.readLine()的內(nèi)容,當(dāng)為true是對(duì)應(yīng)的情況
  //也就是說(shuō)當(dāng)“”(中間沒(méi)有空格)與br.readLine()相等時(shí),就進(jìn)入到while中
  while(!"".equals((header=br.readLine()))){
			parseRequestHeader(header);
			}
		//post和get
		if(br.ready())//post//POST提交方式判斷,如果還有下一行就繼續(xù)讀取信息
		{
			char[] buf=new char[1024];
			int len=br.read(buf);//使用字節(jié)進(jìn)行讀取,因?yàn)檫@一行沒(méi)有回車(chē)換行,readLine無(wú)法判斷是否結(jié)束
			String parameter=new String(buf,0,len);
			parseRequestParamByPost(parameter);//調(diào)用自己創(chuàng)建在本類(lèi)里邊的方法處理POST方式提交的正文信息	
		}
		else
		{//get,get參數(shù)的位置在第一行連接處
			parseRequestParamByGet(requestPath);//調(diào)用自己創(chuàng)建在本類(lèi)里邊的方法處理GET方式提交的正文信息	
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 //GET方法處理
 private void parseRequestParamByGet(String requestPath2) {
		String []str1=requestPath2.split("[?]");//使用“?”分割字符串
		if(str1.length==2)
		{
				parseRequestParamByPost(str1[1]);
		}
		this.requestPath=str1[0];
	}
 //POST方法處理
 private void parseRequestParamByPost(String parameter) {
		 String[] strs=parameter.split("&");
		 if(strs.length>=1)
		 {
			 for(String str:strs)
			 {
				 String [] sp=str.split("=");
  hmparameters.put(sp[0],sp[1]); 
			 }
		 }
	}
	//解析第二行到第八行
	private void parseRequestHeader(String header) throws Exception{
		String[] headHost=header.split(": ");
		 if(headHost.length!=2)
	 {
			 throw new Exception("消息報(bào)頭異常,請(qǐng)重新提交");		 
		 }
		 hmHeader.put(headHost[0],headHost[1]);
	}
	//解析第一行
	private void parseRequestMethodPathProtocol(String str) throws Exception {
		 String[] protocolMethodPath=new String[3];//由于第一行含有三個(gè)內(nèi)容,分割后需要三個(gè)String存儲(chǔ)
		 protocolMethodPath=str.split(" ");//使用空格分割
		 if(protocolMethodPath.length==3)
		 {
		 requestMethod=protocolMethodPath[0];
		 requestPath=protocolMethodPath[1];
		 protocol=protocolMethodPath[2];
		 }
		 else
		 {
			 throw new Exception("首行參數(shù)不合適,請(qǐng)重新提交");
		 }
	}
	//獲得請(qǐng)求的協(xié)議
	public String getProtocol()
	{
		return protocol;
	}
	//獲得請(qǐng)求的方法
	public String getRequestMethod(){
		return requestMethod;
	}
	//獲得請(qǐng)求的路徑
	public String getRequestPath(){
		return requestPath;
	}
	//獲得請(qǐng)求的消息報(bào)頭
	public Map<String,String> getRequestHeader(){
		return this.hmHeader;
	}
	//根據(jù)參數(shù)的名字獲得請(qǐng)求帶過(guò)來(lái)的參數(shù)值
	public String getParameter(String parameterName){
		return hmparameters.get(parameterName);
	}
	//判斷當(dāng)前請(qǐng)求的否是靜態(tài)資源
	public boolean isStaticResource(){
		return true;
	}
	//判斷當(dāng)前請(qǐng)求的否是動(dòng)態(tài)資源
	public boolean isDynamicResource(){
		return true;
	}
	//判斷當(dāng)前請(qǐng)求的否是為空請(qǐng)求(有些瀏覽器會(huì)自動(dòng)發(fā)送空請(qǐng)求)
	public boolean isNullRequest(){
 return isNullRequest;
	}
}

以上內(nèi)容是對(duì)客戶(hù)端(瀏覽器)請(qǐng)求內(nèi)容的處理,即如何進(jìn)行包裝客戶(hù)端請(qǐng)求的信息,并且將其包裝成一個(gè)統(tǒng)一的整體,既然能夠獲取瀏覽器的內(nèi)容,那么,我們就必須采取一定的措施告訴瀏覽器我們找到了你想要的文件,并且將返回給客戶(hù)端,下面我們就來(lái)實(shí)現(xiàn)如何返回給客戶(hù)端想要的信息

二、response響應(yīng)處理

 1、了解response響應(yīng) 

    服務(wù)器在接收和解釋客戶(hù)端的請(qǐng)求消息后,服務(wù)器會(huì)返回給客戶(hù)端一個(gè)HTTP響應(yīng)消息,我們稱(chēng)之為響應(yīng)(response)。其實(shí)也是一個(gè)按照http協(xié)議的規(guī)則拼接而成的一個(gè)字符串
    HTTP響應(yīng)也是由三個(gè)部分組成,分別是: 響應(yīng)狀態(tài)行、消息報(bào)頭、響應(yīng)正文 
    

第一部分 響應(yīng)狀態(tài)行 

        格式如下:
        HTTP-Version Status-Code Reason-Phrase CRLF
例如:
        HTTP/1.1 200 OK
        各部分分別為:
        HTTP-Version表示服務(wù)器HTTP協(xié)議的版本;
        Status-Code表示服務(wù)器發(fā)回的響應(yīng)狀態(tài)代碼; 
        Reason-Phrase表示狀態(tài)代碼的文本描述。
        CRLF表示回車(chē)和換行

    第二部分 消息報(bào)頭

        HTTP消息報(bào)頭包括普通報(bào)頭、請(qǐng)求報(bào)頭、響應(yīng)報(bào)頭、實(shí)體報(bào)頭這四大類(lèi)。
  每一個(gè) 報(bào)頭域 都是由 名字+冒號(hào)+空格+值 組成,消息報(bào)頭域的名字不區(qū)分大小寫(xiě)。它們的作用是描述 客戶(hù)端或者服務(wù)器 的屬性
                 1.普通報(bào)頭:即可用于請(qǐng)求,也可用于響應(yīng),是作為一個(gè)整體而不是特定資源與事務(wù)相關(guān)聯(lián)。
                 2.請(qǐng)求報(bào)頭:允許客戶(hù)端傳遞關(guān)于自身信息和希望的響應(yīng)形式。
                 3.響應(yīng)報(bào)頭:允許服務(wù)器傳遞關(guān)于自身信息的響應(yīng)。
                 4.實(shí)體報(bào)頭:定義被傳送資源的信息。即可用于請(qǐng)求,也可用于響應(yīng)。 

 什么是 MIME Type?

        首先,我們要了解瀏覽器是如何處理內(nèi)容的。在瀏覽器中顯示的內(nèi)容有 HTML、有 XML、有 GIF、還有 Flash ……那么,瀏覽器是如何區(qū)分它們,決定什么內(nèi)容用什么形式來(lái)顯示呢?答案是 MIME Type,也就是該資源的媒體類(lèi)型。媒體類(lèi)型通常是通過(guò) HTTP 協(xié)議,由 Web 服務(wù)器告知瀏覽器的,更準(zhǔn)確地說(shuō),是通過(guò)響應(yīng)的消息報(bào)頭里面的屬性 Content-Type 來(lái)表示的,例如:Content-Type: text/HTML表示內(nèi)容是 text/HTML 類(lèi)型,也就是超文本文件。為什么是“text/HTML”而不是“HTML/text”或者別的什么?MIME Type 不是個(gè)人指定的,是經(jīng)過(guò) ietf 組織協(xié)商,以 RFC 的形式作為建議的標(biāo)準(zhǔn)發(fā)布在網(wǎng)上的,大多數(shù)的 Web 服務(wù)器和用戶(hù)代理都會(huì)支持這個(gè)規(guī)范 (順便說(shuō)一句,Email 附件的類(lèi)型也是通過(guò) MIME Type 指定的)。

      通常只有一些在互聯(lián)網(wǎng)上獲得廣泛應(yīng)用的格式才會(huì)獲得一個(gè) MIME Type,如果是某個(gè)客戶(hù)端自己定義的格式,一般只能以 application/x- 開(kāi)頭。XHTML 正是一個(gè)獲得廣泛應(yīng)用的格式,因此,在 RFC 3236 中,說(shuō)明了 XHTML 格式文件的 MIME Type 應(yīng)該是 application/xHTML+XML。當(dāng)然,處理本地的文件,在沒(méi)有人告訴瀏覽器某個(gè)文件的 MIME Type 的情況下,瀏覽器也會(huì)做一些默認(rèn)的處理,這可能和你在操作系統(tǒng)中給文件配置的 MIME Type 有關(guān)。比如在 Windows 下,打開(kāi)注冊(cè)表的“HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type”主鍵,你可以看到所有 MIME Type 的配置信息

每個(gè)MIME類(lèi)型由兩部分組成,前面是數(shù)據(jù)的大類(lèi)別,例如聲音audio、圖象image等,后面定義具體的種類(lèi)。

常見(jiàn)的MIME類(lèi)型

超文本標(biāo)記語(yǔ)言文本 .html,.html text/html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF圖形 .gif image/gif
JPEG圖形 .ipeg,.jpg image/jpeg
au聲音文件 .au audio/basic
MIDI音樂(lè)文件 mid,.midi audio/midi,audio/x-midi
RealAudio音樂(lè)文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar

    第三部分 響應(yīng)正文

        響應(yīng)正文就是服務(wù)器返回的資源的內(nèi)容 

 2、實(shí)現(xiàn)

      首先,我們需要進(jìn)行抽象,即將瀏覽器想要的信息,即如下內(nèi)容包裝起來(lái),如下所示,我們將其包裝成一個(gè)接口,在抽象時(shí)我們必須認(rèn)識(shí)到用戶(hù)可能會(huì)犯的錯(cuò)誤,所以盡量使用重載的方法進(jìn)行避免,在下面的接口中,使用了重載進(jìn)行處理部分方法:

package com.sample.http;
import java.io.OutputStream;
import java.io.PrintWriter;
//http協(xié)議的響應(yīng)
public interface HttpResponse {
	//獲得一個(gè)指向客戶(hù)端的字節(jié)流
	public OutputStream getOutputStream()throws Exception;
	//獲得一個(gè)指向客戶(hù)端的字符流
	public PrintWriter getPrintWriter()throws Exception;
	//設(shè)置響應(yīng)的狀態(tài)行 參數(shù)為String類(lèi)型
	public void setStatusLine(String statusCode);
	//設(shè)置響應(yīng)的狀態(tài)行 參數(shù)為int類(lèi)型
	public void setStatusLine(int statusCode);
	//設(shè)置響應(yīng)消息報(bào)頭
	public void setResponseHeader(String hName,String hValue);
	//設(shè)置響應(yīng)消息報(bào)頭中Content-Type屬性
	public void setContentType(String contentType);
	//設(shè)置響應(yīng)消息報(bào)頭中Content-Type屬性 并且同時(shí)設(shè)置編碼
	public void setContentType(String contentType,String charsetName);
	//設(shè)置CRLF 回車(chē)換行 \r\n
	public void setCRLF();
	//把設(shè)置好的響應(yīng)狀態(tài)行、響應(yīng)消息報(bào)頭、固定空行這三部分寫(xiě)給瀏覽器
	public void printResponseHeader();
	//把響應(yīng)正文寫(xiě)給瀏覽器
	public void printResponseContent(String requestPath);		
}

在接口中,我們能夠看到詳細(xì)的解釋?zhuān)旅嫖覀兙蛠?lái)實(shí)現(xiàn)接口中的方法:

package com.sample.http;
<pre name="code" class="java">import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
 
import com.sample.utils.ConfigUtils;
import com.sample.utils.StatusCodeUtils;
//http協(xié)議的響應(yīng)
public class HttpResponseImpl implements HttpResponse {
	 //聲明初始變量
	Socket s;//客戶(hù)端socket
	OutputStream os;//輸出端字節(jié)流
	BufferedWriter bw;//輸出端字符流
	PrintWriter pw;
	StringBuffer sbuffer;//放狀態(tài)行,\r\n ,
	FileInputStream fis;
	File file;
	//構(gòu)造器
	public HttpResponseImpl(Socket s) {
  this.s=s;
  System.out.println("HttpRequestImpl(Socket s)");
  os=null;
  bw=null;
  pw=null;
  sbuffer=new StringBuffer();//初始化,記得,否則以下的操作會(huì)遇見(jiàn)空指針異常
  fis=null;
  file=null; 			
  getInfos();
	}
	 
	private void getInfos() {
			try {
				os=s.getOutputStream();
				bw=new BufferedWriter(new OutputStreamWriter(os,"GBK"));
				pw=new PrintWriter(bw);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	//獲得一個(gè)指向客戶(hù)端的字節(jié)流
	public OutputStream getOutputStream()throws Exception
	{
		return os;
	}
	//獲得一個(gè)指向客戶(hù)端的字符流
	public PrintWriter getPrintWriter()throws Exception
	{
		return pw;
	}
	//設(shè)置響應(yīng)的狀態(tài)行 參數(shù)為String類(lèi)型
	public void setStatusLine(String statusCode)
	{
		String str=StatusCodeUtils.getStatusCodeValue(statusCode);
		//System.out.println(str+"------"+str.length());
		sbuffer.append("HTTP/1.1 "+statusCode+" "+str);
		setCRLF();
	}
	//設(shè)置響應(yīng)的狀態(tài)行 參數(shù)為int類(lèi)型
	public void setStatusLine(int statusCode)
	{
		setStatusLine(statusCode+"");//將int類(lèi)型轉(zhuǎn)化為String類(lèi)型
	}
	//設(shè)置響應(yīng)消息報(bào)頭
	public void setResponseHeader(String hName,String hValue)
	{
		sbuffer.append(hName+": "+hValue);
		setCRLF();
	}
	//設(shè)置響應(yīng)消息報(bào)頭中Content-Type屬性
	public void setContentType(String contentType)
	{
		setResponseHeader("Content-Type",contentType);
	}
	//設(shè)置響應(yīng)消息報(bào)頭中Content-Type屬性 并且同時(shí)設(shè)置編碼
	public void setContentType(String contentType,String charsetName)
	{//text/html;charset=utf-8
		setContentType(";charset= "+charsetName);
	}
	//設(shè)置CRLF 回車(chē)換行 \r\n
	public void setCRLF()
	{
		sbuffer.append("\r\n");
	}
	//把設(shè)置好的響應(yīng)狀態(tài)行、響應(yīng)消息報(bào)頭、固定空行這三部分寫(xiě)給瀏覽器
	public void printResponseHeader()
	{
		//設(shè)置setResponseLine,setResponseHeader,setResponseType
		String res=sbuffer.toString();
		pw.print(res);
		pw.flush();
	}
	//把響應(yīng)正文寫(xiě)給瀏覽器
	public void printResponseContent(String requestPath)
	{
		//響應(yīng)正文
		String getPath= requestPath;//客戶(hù)請(qǐng)求的地址
		String webHome=(new ConfigUtils()).getConfigValue("rootPath");	
		System.out.println("配置文件中目錄:"+webHome);//輸出從配置文件中獲取的地址
		file=new File(webHome+getPath);
		if(file.exists())//如果文件存在就執(zhí)行
		{
		try {
			fis=new FileInputStream(file);
			byte[] buf=new byte[1024];
			int len=-1;
			while((len=fis.read(buf))!=-1)
			{
				//String str=buf.toString();
				//bw.write(str);//字符流寫(xiě)過(guò)去是一個(gè)地址,因?yàn)閷?xiě)過(guò)去之后需要瀏覽器解析,如果是圖片或者其他(圖片或視頻是字節(jié)流)的該怎么解析呢?
				//System.out.println(str);
				os.write(buf, 0, len);
			}
			bw.flush();
			os.flush();//os要不要關(guān)???
		} catch (IOException e) {
			e.printStackTrace();
		}finally
		{
			try {
				if(bw!=null)
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		}
	}
}

在Eclipse中寫(xiě)完以上代碼我們會(huì)發(fā)現(xiàn),其中有多處錯(cuò)誤信息,其原因是我們沒(méi)有進(jìn)行創(chuàng)建以上代碼所要求的類(lèi),現(xiàn)在我們進(jìn)行創(chuàng)建,其使用方法請(qǐng)參見(jiàn):java.util 類(lèi) Properties    ,使用參考中的方法,我們能夠進(jìn)行對(duì)所需要的信息進(jìn)行配置,在以上代碼中使用的地方有兩處,分別是【注意:這樣做的好處是增減了項(xiàng)目的靈活性,用戶(hù)能夠在不查看代碼的情況下隨時(shí)更改配置文件等一些文件的信息,】:

(1)設(shè)置狀態(tài)行處

//設(shè)置響應(yīng)的狀態(tài)行 參數(shù)為String類(lèi)型
	public void setStatusLine(String statusCode)
	{
		String str=StatusCodeUtils.getStatusCodeValue(statusCode);
		//System.out.println(str+"------"+str.length());
		sbuffer.append("HTTP/1.1 "+statusCode+" "+str);
		setCRLF();
	}

其中StatusCodeUtils類(lèi)創(chuàng)建如下所示,而對(duì)于status_code.properties文件存放在下載的準(zhǔn)備文件中的/webservlet/project/中,直接復(fù)制到項(xiàng)目中即可:

package com.sample.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class StatusCodeUtils {
	private static Properties p;
	static 
	{
		InputStream in=null;
		p=new Properties();
		try {
			//讀了xx.properties文件
			in=StatusCodeUtils.class.getResourceAsStream("status_code.properties");
			//放置到p中,即放properties文件中的key,value
			p.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally
		{
			if(in!=null)
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	public static String getStatusCodeValue(String status)
	{ 
		return p.getProperty(status);
	}
	public static String getStatusCodeValue(int status)
	{ 
		return getStatusCodeValue(status+"");//沒(méi)有空格
	}
	/*public static void main(String[] args) {//輸出測(cè)試
	//Properties p=new Properties();
	// p.setProperty("rootPath","ddd");
	//System.out.println(p.get("rootPath"));
		System.out.println(getStatusCodeValue("304"));
		System.out.println(getStatusCodeValue("200"));
	}*/
}

(2)響應(yīng)正文處:

//響應(yīng)正文
		String getPath= requestPath;//客戶(hù)請(qǐng)求的地址
		String webHome=(new ConfigUtils()).getConfigValue("rootPath");	
		System.out.println("配置文件中目錄:"+webHome);//輸出從配置文件中獲取的地址
		file=new File(webHome+getPath);

 在響應(yīng)正文中使用了ConfigUtils類(lèi)進(jìn)行了項(xiàng)目路徑的獲取,代碼如下所示,對(duì)于config.properties(注意:此文件中文件路徑應(yīng)該注意,我使用的是Linux系統(tǒng),文件結(jié)構(gòu)是/home/***,而對(duì)于windows系統(tǒng),目錄結(jié)構(gòu)為:"C://webapps/*****,最好在地址欄復(fù)制地址,寫(xiě)到配置中")文件也在準(zhǔn)備文件中,請(qǐng)自行下載,然后復(fù)制到項(xiàng)目中:就是下面這個(gè)東西,路徑配置合適,然后你就可以將自己的項(xiàng)目放在webapps目錄下,讓自己的電腦作為服務(wù)器供其他人訪問(wèn)自己的網(wǎng)站了

ConfigUtils路徑配置類(lèi),用于獲取項(xiàng)目文件目錄位置

package com.sample.utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public class ConfigUtils {
	private static Properties p;
	static 
	{
		InputStream in=null;
		OutputStream on=null;
		p=new Properties();
		try {
			//讀了xx.properties文件
			in=ConfigUtils.class.getResourceAsStream("config.properties");
			//放置到p中,即放properties文件中的key,value
			p.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally
		{
			if(in!=null)
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	public static String getConfigValue(String config)
	{ 
		return p.getProperty(config);
	}
	public static void main(String[] args) {//輸出測(cè)試
	//	Properties p=new Properties();
	//	p.setProperty("rootPath","ddd");
	//	System.out.println(p.get("rootPath"));
		System.out.println(getConfigValue("rootPath"));
	}
}

到此為止,我們已經(jīng)實(shí)現(xiàn)了服務(wù)器的主要任務(wù),接受請(qǐng)求和處理請(qǐng)求,下面我們進(jìn)行測(cè)試:

寫(xiě)一個(gè)測(cè)試類(lèi)如下:

package com.sample.http;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class ServerTest {
	public static void main(String[] args) {
		//聲明變量
 ServerSocket ss=null;
 Socket s=null;
 boolean flag=true;
 try {
 	int port=10002;
 	System.out.println("Server Port:"+port);
					ss=new ServerSocket(port);
					//while(flag)
					{
						//接受客戶(hù)端發(fā)送過(guò)來(lái)的Socket
						s=ss.accept();
						HttpRequestImpl request=new HttpRequestImpl(s);							
						//	用于測(cè)試收到的信息
						System.out.println("獲取的路徑:"+request.getRequestPath());
						System.out.println("獲取的:"+request.getProtocol());
						System.out.println("獲取的:"+request.getRequestMethod());
						System.out.println(request.getParameter("name"));
						System.out.println(request.getParameter("id"));					
						Map<String,String> m=request.getRequestHeader();
						Set<Entry<String,String>> set=m.entrySet();
						Iterator it=set.iterator();
						while(it.hasNext())
						{
							Entry entry=(Entry<String, String> )it.next();
							System.out.println(entry.getKey()+"----"+entry.getValue());
						}
					 //寫(xiě)響應(yīng)給瀏覽器
						/*
						 * 封裝:
						 * */
						//輸出流
						HttpResponseImpl response=new HttpResponseImpl(s);												
						response.setStatusLine(200);
						response.setContentType("text/html");
						response.printResponseHeader();
						response.setCRLF();
						response.printResponseHeader();
						response.printResponseContent(request.getRequestPath());
						//用于輸出信息
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
	}
}

在瀏覽器中輸入地址回車(chē):http://127.0.0.1:10002/test.html?id=1212&name=suguniang ,能夠看到瀏覽器解析后的界面,當(dāng)其他電腦訪問(wèn)時(shí)(其他電腦指的是同一個(gè)域內(nèi)的),只要將127.0.0.1修改為本地的ip地址即可

此時(shí)控制臺(tái)上也輸出相應(yīng)的信息:

web服務(wù)器項(xiàng)目中靜態(tài)請(qǐng)求和動(dòng)態(tài)請(qǐng)求處理:http://chabaoo.cn/article/191243.htm

到此這篇關(guān)于淺談web服務(wù)器項(xiàng)目中request請(qǐng)求和response的相關(guān)響應(yīng)處理的文章就介紹到這了,更多相關(guān)web服務(wù)器 request請(qǐng)求 response響應(yīng)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java連接Mysql數(shù)據(jù)庫(kù)詳細(xì)代碼實(shí)例

    Java連接Mysql數(shù)據(jù)庫(kù)詳細(xì)代碼實(shí)例

    這篇文章主要介紹了Java連接Mysql數(shù)據(jù)庫(kù)詳細(xì)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • idea中將單個(gè)java類(lèi)導(dǎo)出為jar包文件的方法

    idea中將單個(gè)java類(lèi)導(dǎo)出為jar包文件的方法

    這篇文章主要給大家介紹了關(guān)于idea中將單個(gè)java類(lèi)導(dǎo)出為jar包文件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Springboot整合kafka的示例代碼

    Springboot整合kafka的示例代碼

    這篇文章主要介紹了Springboot整合kafka的示例代碼,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • java讀取文件:char的ASCII碼值=65279,顯示是一個(gè)空字符的解決

    java讀取文件:char的ASCII碼值=65279,顯示是一個(gè)空字符的解決

    這篇文章主要介紹了java讀取文件:char的ASCII碼值=65279,顯示是一個(gè)空字符的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • java并發(fā)等待條件的實(shí)現(xiàn)原理詳解

    java并發(fā)等待條件的實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了java并發(fā)等待條件的實(shí)現(xiàn)原理詳解,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-11-11
  • Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則

    Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則

    這篇文章主要介紹了Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • java實(shí)現(xiàn)將漢語(yǔ)轉(zhuǎn)換為拼音功能

    java實(shí)現(xiàn)將漢語(yǔ)轉(zhuǎn)換為拼音功能

    這篇文章主要介紹了java實(shí)現(xiàn)將漢語(yǔ)轉(zhuǎn)換為拼音功能,非常不錯(cuò),具有參考借鑒價(jià)值 ,需要的朋友可以參考下
    2017-05-05
  • 詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式

    目前Java開(kāi)發(fā)包中包含了對(duì)動(dòng)態(tài)代理的支持,但是其實(shí)現(xiàn)只支持對(duì)接口的的實(shí)現(xiàn)。這篇文章主要介紹了詳解java動(dòng)態(tài)代理的2種實(shí)現(xiàn)方式 ,有興趣的可以了解一下。
    2016-11-11
  • 基于Java解決華為機(jī)試實(shí)現(xiàn)密碼截取?

    基于Java解決華為機(jī)試實(shí)現(xiàn)密碼截取?

    這篇文章主要介紹了基于Java解決華為機(jī)試實(shí)現(xiàn)密碼截取,文章圍繞主題相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,具有一的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助
    2022-02-02
  • 探討如何在Eclipse中過(guò)濾版本控制文件.svn

    探討如何在Eclipse中過(guò)濾版本控制文件.svn

    本篇文章是對(duì)在Eclipse中過(guò)濾版本控制文件.svn的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07

最新評(píng)論