HttpServletRequest與HttpServletResponse

一. HttpServletRequest

1. 什麼是HttpServletRequest對象?

HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息

都封裝在這個對象中,開發人員通過這個對象的方法,可以獲得客戶這些信息。也就是說所有的請求信息都封裝

在這裏,由服務器負責封裝。

2. HttpServletRequest對象的作用是用於獲取請求數據。

3. Request常用方法

(1) 獲取請求行信息:

① request.getMethod();   獲取請求的方式

② request.getRequestURI(); / request.getRequestURL();  獲取請求的資源

③ request.getProtocol();  獲取請求的http協議版本

public class ExampleDemo1 extends HttpServlet {
	/**
	 * (1)tomcat服務器接收到瀏覽器發送的請求數據,然後封裝到HttpServletRequest對象
	 * (2)tomcat服務器調用doGet方法,然後把request對象傳入到Servlet中。
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/**
		 * (3)從request對象取出請求數據。
		 */
		t1(request);
	}

	private void t1(HttpServletRequest request) {
		System.out.println("請求的方式:" + request.getMethod());// 請求方式
		System.out.println("URI:" + request.getRequestURI());// 請求資源
		System.out.println("URL:" + request.getRequestURL());// 也是獲取請求資源,只是兩種不同的表現形式
		System.out.println("http協議版本:" + request.getProtocol());// http協議
	}
}

運行結果如下圖所示:


(2) 獲取請求頭信息:

request.getHeader("名稱");  根據請求頭獲取請求值

request.getHeaderNames();  獲取所有的請求頭名稱

public class ExampleDemo2 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		t2(request);
	}

	private void t2(HttpServletRequest request) {
		/*
		 * 獲取請求頭 request.getHeader("頭名稱");根據頭名稱拿到請求頭的內容。
		 */
		String host = request.getHeader("Host");
		System.out.println(host);
		// 遍歷所有請求頭
		Enumeration<String> enums = request.getHeaderNames();// 得到所有的請求頭名稱列表
		while (enums.hasMoreElements()) { // 判斷是否有下一個元素
			String headerName = enums.nextElement();// 取出下一個元素,結果仍然是一個頭名稱,我們可以用頭名稱拿到它對應的值。
			String headerValue = request.getHeader(headerName);
			System.out.println(headerName + ":" + headerValue);
		}
	}
}

運行結果如下圖所示:


(3) 獲得實體內容

request.getInputStream();  獲取實體內容數據

public class ExampleDemo3 extends HttpServlet {
	// 爲了接受post方式提交的請求。如果是post方式提交的請求一定要用doPost方法
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 獲取請求的實體內容
		 */
		InputStream in = request.getInputStream(); // 得到實體內容
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = in.read(buf)) != -1) {
			String str = new String(buf, 0, len);
			System.out.println(str);
		}
	}
}

運行結果如下圖所示:


4. 表單傳遞的請求參數如何獲取?

(1) 請求參數存在的位置:

① 如果是GET請求方式,參數放在URI的後面。

② 如果是POST請求方式,參數放在實體內容中。

(2) 獲取參數的方式:

① 獲取GET請求的參數的方式:request.getQueryString();

② 獲取POST請求的參數的方式:request.getInputStream();

(3) 存在的問題:以上兩種方式不通用,而且獲取到的參數還需要進一步的解析,所以可以採用統一方便的獲取參

數的方式。

(4) 統一獲取參數的方式:

① request.getParameter("參數名");  根據參數名獲取參數值(注意,只能獲取一個參數的參數值)

② request.getParameterValue("參數名“);  根據參數名獲取參數值(可以獲取多個參數的參數值)

③ request.getParameterNames();  獲取所有參數名稱列表

/*
 * 獲取GET方式和POST方式提交的參數
 */
public class RequestDemo2 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 統一方便的獲取請求參數的方法
		 */
		// getparameter根據參數名得到參數值(但是隻能獲取一個值的參數,不能獲取多選框的值)
		String name = request.getParameter("name");
		String password = request.getParameter("password");
		System.out.println("用戶名:" + name + "  密碼:" + password);

		System.out.println("=================================");
		// 返回的是一個迭代器,可以遍歷所有的參數
		Enumeration<String> enums = request.getParameterNames();
		while (enums.hasMoreElements()) {
			String paraName = enums.nextElement();

			/*
			 * getParameterValues(name):根據參數名獲取參數值(可以獲取同名參數名的多個參數值)
			 */
			// 如果參數名是hobit,則調用getParameterValues
			if ("hobit".equals(paraName)) {
				System.out.println(paraName + ":");
				String[] hobits = request.getParameterValues("hobit");
				for (String h : hobits) {
					System.out.println(h + ",");
				}
			} else {
				String paraValue = request.getParameter(paraName);
				System.out.println(paraName + ":" + paraValue);
			}
		}
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 調用doGet方式
		this.doGet(request, response);
	}
}

運行結果如下圖所示:


5. request常見應用:

(1) 獲取瀏覽器類型;

(2) 防盜鏈;

(3) 各種表單輸入項數據的獲取,比如:text、password、radio、checkbox、file、select、textarea、

hidden、imge、button;

(4) 請求參數的中文亂碼問題。

二. HttpServletResponse

1. 簡介

(1) Web服務器收到客戶端的http請求,會針對每一次請求,分別創建一個用於代表請求的request對象,和代表

響應的response對象。

(2) request對象和response對象既然代表請求和響應,那我們要獲取客戶端提交過來的數據,只需要找request

對象就行了;如果要向客戶端輸出數據,只需要找response對象即可。

2. HttpServletResponse對象

HttpServletResponse對象代表了服務器的響應。這個對象中封裝了向客戶端發送數據、發送響應頭、發送響應

狀態碼的方法,該對象的作用是用來設置響應數據。

3. HttpServletResponse對象修改響應信息

(1) 修改響應行信息: 

response.setStatus();  設置狀態碼

(2) 修改響應頭信息: 

response.setHeader("name","value");  設置響應頭

(3) 修改實體內容:

response.getWriter().writer();  發送字符實體內容

response.getOutputStream().writer();  發送字節實體內容

4.實例:

/*
 * 設置響應的信息
 */
public class ResponseDemo1 extends HttpServlet {
	/*
	 * (1)tomcat服務器把請求信息封裝到HttpServletRequest對象中,並且把響應信息封裝到HttpServletresponse中去
	 * (2)tomcat服務器先調用service方法,在service方法中調用doGet方法。傳入request和response對象
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * (3)通過response對象改變響應信息。
		 */
		// 3.1響應行
		// response.setStatus(404);//修改狀態碼,會影響瀏覽器的行爲
		response.sendError(404);// 發送404的狀態碼+404的錯誤頁面。但是發404是沒有意義的。
		// 3.2改變響應頭
		response.setHeader("server", "JBoss");
		// 3.3改變實體內容:實體內容就是我們頁面看的到的部分(瀏覽器直接能夠看到的內容就是實體內容)。
		// 兩種改變方式
		response.getWriter().write("01.hello world");// writer裏面是字符串,所以發送的內容也是字符內容。
		response.getOutputStream().write("02.hello world".getBytes());// 發送的是字節內容。
	}
	/*
	 * (4)tomcat服務器把response對象的內容轉換成響應格式內容,再發送給瀏覽器解析
	 */
}

5. Response細節:

(1) getOutputStream和getWriter方法分別用於得到輸出二進制數據、輸出文本數據的ServletOuputStream、

Printwriter對象。

(2) getOutputStream和getWriter這兩個方法互相排斥,調用了其中的任何一個方法後,就不能再調用另一方

法。  

(3) Servlet程序向ServletOutputStream或PrintWriter對象中寫入的數據將被Servlet引擎從response裏面獲

取,Servlet引擎將這些數據當作響應消息的正文,然後再與響應狀態行和各響應頭組合後輸出到客戶端。 

(4) Serlvet的service方法結束後,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否

已經調用過close方法,如果沒有,Servlet引擎將調用close方法關閉該輸出流對象。

三. response常見應用

1. 案例一 請求重定向(Location)

(1) 請求重定向是指:一個Web資源收到客戶端請求後,通知客戶端去訪問另外一個Web資源,這稱之爲請求重

定向。

(2) 應用場景:用戶註冊。

(3) 實現方式:response.sendRedirect();

(4) 實現原理:

發送一個302狀態碼和location的響應頭即可實現重定向。

(5) 原理圖及分析:


① 瀏覽器發送一個請求到服務器請求一個資源,tomcat服務器中有一個ResponseDemo2,當瀏覽器發送請

求,它就會產生一個響應,這個Servlet就會發送狀態碼和響應頭給瀏覽器;

② 瀏覽器是認識302狀態碼的,當瀏覽器得到302狀態碼之後,會再次自動向服務器發出一個請求,請求的地址

就是location的value值的地址,所以location的地址值是:/zw_http/adv.html,當瀏覽器得到302狀態碼之

後,會自動向瀏覽器發送一個請求,就請求這個資源,服務器中有這個資源就會做出響應。所以就看到請求重定

向的效果;

③ 請求重定向瀏覽器一共向服務器發出2次請求;

④ 它的地址欄是由第二次請求決定的,用第二次的地址決定瀏覽器應該顯示什麼。也就相當於瀏覽器在地址欄中

輸入adv.html的地址。

(6) 實例:

public class ResponseDemo2 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * response.setStatus(302);//發送一個302狀態碼 response.setHeader("location",
		 * "/zw_http/adv.html");//location的響應頭採用的是URI的寫法。
		 */
		response.sendRedirect("/zw_http/adv.html");// 簡寫
	}
}

2. 案例二 使用Refresh實現定時跳轉(定時刷新)

(1) 實現原理:

瀏覽器認識Refresh響應頭,得到Refresh響應頭之後重新再請求當前資源。比如:註冊完一個網站用戶後,3秒

之後跳轉到首頁。

(2) 實例:

public class ResponseDemo3 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// response.setHeader("refresh", "1");//每隔1秒刷新此頁面
		response.setHeader("refresh", "3;url=/zw_http/adv.html");// 隔3秒之後跳轉到adv.html
	}
}

3. 案例三 使用content-Type實現向瀏覽器輸出圖片

/*
 * 案例三:content-Type的作用:
 * 服務器發送給瀏覽器的數據類型及內容編碼
 */
public class ResponseDemo4 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 1.服務器發送給瀏覽器的數據類型
		 */
		/*
		 * //response.setHeader("content-type","text/html");
		 * //response.setContentType("text/html");//和上面代碼等價,推薦使用此方法。
		 * response.getWriter().write(
		 * "<html><head><title>this is title</title></head><body>this is body</body></html>"
		 * );
		 */
		response.setContentType("image/jpg");
		/*
		 * 發送圖片
		 */
		FileInputStream in = new FileInputStream(new File("e:/mm.jpg"));// 先把圖片讀進來
		// 邊讀邊寫
		byte[] buf = new byte[1024];
		int len = 0;
		while ((len = in.read(buf)) != -1) {
			response.getOutputStream().write(buf, 0, len);
		}
	}
}











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章