Servlet——HttpServletRequest對象詳解

        Servlet——HttpServletRequest對象詳解                                                                   

HttpServletRequest對象表明客戶端的請求,當客戶端經過HTTP協議訪問服務器時,HTTP請求頭中的全部信息都封裝在這個對象中,開發人員經過這個對象的方法,能夠得到客戶的這些信息。html

======================================================================================java

 

HttpServletRequest經常使用方法web

getRequestURL方法返回客戶端發出請求時的完整URL getRequestURI方法返回請求行中的資源名部分 getQueryString方法返回請求行中的參數部分(參數名+值) getRemoteAddr方法返回發出請求的客戶機的IP地址 getRemoteHost方法返回發出請求的客戶機的完整主機名 getRemotePort方法返回web服務器所使用的網絡端口號 getLocalPort方法返回web服務器所使用的網絡端口號 getLocalAddr方法返回web服務器的IP地址 getLocalName方法返回web服務器的主機名

在Servlet中做以下測試:瀏覽器

// 獲得URL
		String url = request.getRequestURL().toString();
		System.out.println("URL:"+url);
		out.println("URL:"+url+"<br>");
		// 獲得URI
		String uri = request.getRequestURI();
		System.out.println("URI:"+uri);
		out.println("URI:"+uri+"<br>");
		// 獲得參數字符串
		String query_string = request.getQueryString();
		System.out.println("QueryString:"+query_string);
		out.println("QueryString:"+query_string+"<br>");
		// 獲得請求方的IP地址
		// 能夠以此來封殺某些IP
		String remote_addr = request.getRemoteAddr();
		System.out.println("RemoteAddr:"+remote_addr);
		out.println("RemoteAddr:"+remote_addr+"<br>");
		// 獲得請求方的完整主機名
		String remote_host = request.getRemoteHost();
		System.out.println("RemoteHost:"+remote_host);
		out.println("RemoteHost:"+remote_host+"<br>");
		//獲得請求方的網絡端口號
		int remote_port = request.getRemotePort();
		System.out.println("RemotePort:"+remote_port);
		out.println("RemotePort:"+remote_port+"<br>");
		//獲得服務器本機使用的網絡端口號
		int local_port = request.getLocalPort();
		System.out.println("LocalPort:"+local_port);
		out.println("LocalPort:"+local_port+"<br>");
		//獲得服務器本機的IP地址
		String local_addr = request.getLocalAddr();
		System.out.println("LocalAddr:"+local_addr);
		out.println("LocalAddr:"+local_addr+"<br>");
		// 獲得服務器本機的主機名
		String local_name = request.getLocalName();
		System.out.println("LocalName:"+local_name);
		out.println("LocalName:"+local_name+"<br>");

瀏覽器運行結果:服務器

 

======================================================================================網絡

HttpServletRequest的常見應用app

----------------------------------------------------------------------------------------------------------------------------------------------------post

1.獲取客戶機請求頭測試

getHeader方法獲取某一個header的內容
getHeaders方法(若是頭名字相同,返回Enumeration,用得比較少)
getHeaderNames方法獲取全部的http消息頭

測試:url

 

//getHeader 經過消息頭,來獲取信息
		// 好比要獲取http請求的Host
		String host = request.getHeader("Host");
		System.out.println("Host:"+host);
		
		System.out.println("-----------------");
		
		//getHeaderNames方法獲取全部的消息頭
		// 需求:請把整個http請求的消息所有獲取
		Enumeration<String> headers= request.getHeaderNames();
		while(headers.hasMoreElements()){
			// 取出消息頭的名字
			String headername = headers.nextElement();
			System.out.println(headername+":"+ request.getHeader(headername));
		}

 

服務器輸出結果:

Host:localhost:8080
-----------------
host:localhost:8080
connection:keep-alive
cache-control:max-age=0
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8

---------------------------------------------------------------------------------------------------------------------------------------------------- 2.獲取客戶機請求參數

getParameter方法
getParameterValues(String name)
getParameterNames()方法

在這裏,getParameter方法返回一個只有一個值的參數,getParameterValues方法返回一個能夠有多個值的參數,好比用於獲取複選框的選項。

 

案例:獲取用戶經過表單提交的內容。 界面部分:

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>Form</TITLE></HEAD>");
		out.println("  <BODY>");
		out.println("     <form action='RegisterCL' method='post'>");
		out.println("     用戶名:<input type='text' name='username'/><br><br>");
		out.println("     密 碼:<input type='password' name='pwd'/><br><br>");
		out.println("     性 別:<input type='radio' name='sex' value='男'/>男<input type='radio' name='sex' value='女'/>女<br><br>");
		out.println("     愛 好:<input type='checkbox' name='hobby' value='音樂'/>音樂<input type='checkbox' name='hobby' value='籃球'/>籃球<input type='checkbox' name='hobby' value='電影'/>電影<br><br>");
		out.println("     所在城市:<select name='city'><option value='北京'>北京</option><option value='重慶'>重慶</option></select><br><br>");
		out.println("     你的介紹:<textarea cols='20' rows='10' name='intro'>請輸入介紹...</textarea><br><br>");
		out.println("     提交照片:<input type='file' name='photo'/><br><br>");
		// hidden表單
		// 何時使用hidden傳數據:1.不但願用戶看到該數據  2.不但願影響界面,同時業務邏輯又要使用該數據
		out.println("     <input type='hidden' value='abc' name='hidden1'/>");
		out.println("     <input type='submit' value='提交'/>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}

接收信息的Servlet代碼:

 

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		String u = request.getParameter("username");
		String p = request.getParameter("pwd");
		String sex = request.getParameter("sex");
		// 若是接收復選框的內容,則應該使用getParameterValues
		// 若是複選框一個都沒有選擇,則會返回null,因此下面要進行判斷
		String hobbies[] = request.getParameterValues("hobby");
		String city = request.getParameter("city");
		String intro = request.getParameter("intro");
		String hidden1 = request.getParameter("hidden1");
		
		out.println("用戶名:"+u+"<br>");
		out.println("密 碼:"+p+"<br>");
		out.println("性 別:"+sex+"<br>");
		if(hobbies == null){
			out.println("你沒有愛好<br>");
		}else{
			out.println("你的愛好有:<br>");
			out.println("<ul>");
			for(int i=0;i<hobbies.length;i++){
				out.println("<li>"+hobbies[i]+"</li>");
			}
			out.println("</ul>");
		}
		out.println("所在城市:"+city+"<br>");
		out.println("我的介紹:"+intro+"<br>");
		out.println("隱藏控件傳遞的數據是:"+hidden1+"<br>");
	}

運行結果:

 

提交以後:

---------------------------------------------------------------------------------------------------------------------------------------------------- 3.實現請求轉發

請求轉發指一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理。 請求轉發必定要和HttpServletResponse.sendRedirect所表示的請求重定向區別開來!

一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理,稱之爲請求轉發 一個web資源收到客戶端請求後,通知瀏覽器去訪問另一個web資源,稱之爲請求重定向。

HttpServletRequest對象提供了一個getRequestDispatcher方法,該方法返回一個RequestDispatcher對象,調用這個對象的forword方法能夠實現請求轉發。

 

那麼什麼叫作請求轉發呢?假如咱們此時要經過request請求轉發的方式將數據帶到下一個頁面該怎麼作?看下面一個案例:

假如咱們的項目有三個Servlet,分別是Login、Servlet1和Servlet2,Servlet1接收Login表單post過來的數據,而後請求轉發到Servlet2進行處理。

Login的代碼:

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		//返回一個界面
		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>LoginServlet</TITLE></HEAD>");
		out.println("  <BODY>");
		out.println("<h1>用戶登陸</h1>");
		//action 應該這樣寫 /web應用名稱/Servlet的url
		out.println("<form action='/requestForward/Servlet1' method='post'>");
		out.println("用戶名:<input type='text' name='username'/><br><br>");
		out.println("密 碼:<input type='password' name='password'><br><br>");
		out.println("<input type='submit' value='登陸'><br>");
		out.println("</form>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}

Servlet1的代碼:

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		// 接收用戶名
		String u = request.getParameter("username");
		
		// 把u放入request域對象
		request.setAttribute("username", u);
		
		// 表示使用轉發的方法把request和response對象傳遞給下一個Servlet
		// 這裏不用帶web應用名稱
		request.getRequestDispatcher("/Servlet2").forward(
				request, response);
	}

Servlet2的代碼:

 

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		
		PrintWriter out = response.getWriter();
		
		String u = request.getAttribute("username").toString();
		out.println("接收到的用戶名是:"+u);
	}

能夠看到,Servlet1接收Login傳遞過來的數據,而後將數據放入了request域對象,而後將request對象和response對象使用轉發的方法傳遞給了Servlet2,也就是說,Servlet2中的request對象和response對象其實就是Servlet1中的。

 

能夠經過下述時序圖瞭解這個交互過程:


從時序圖中能夠看到,瀏覽器只發出了一次請求,接收到了一次結果。而從Servlet1到Servlet2的轉發過程只是發生在服務器內部的,瀏覽器並不知道。因此說,瀏覽器的地址欄此時應該停留在http://localhost:8080/RequestTest/Servlet1,其實無論服務器內部轉發多少次,瀏覽器都不會知道,它的地址欄也就不會發生變化,這一切都是發生在服務器內部的。

而sendRedirect請求重定向與此不一樣,請求重定向是服務器告訴瀏覽器接下來應該訪問的WEB資源,瀏覽器收到這個通知以後會去請求這個資源,這是發生在瀏覽器的兩次不一樣的請求,因此地址欄也會發生變化。

這裏要注意的是:

一、使用forward不能轉發到該web應用以外的url。 二、由於forward是發生在web服務器的,不是瀏覽器,因此Servlet1和Servlet2使用的是同一個request和response對象。 三、使用sendRedirect()方法不可以經過request.setAttribute()方法把屬性傳遞給下一個Servlet。很顯然,這是兩次不一樣的請求,request對象都不同,怎麼可能經過request傳遞數據。

----------------------------------------------------------------------------------------------------------------------------------------------------

下面總結一下請求重定向(sendRedirect)和請求轉發的區別: 【1】RequestDispatcher.forward方法只能將請求轉發給同一個WEB應用中的組件;而HttpServletResponse.sendRedirect方法還能夠重定向到同一個站點上的其餘應用程序中的資源,甚至是使用絕對URL重定向到其餘站點的資源。 【2】若是傳遞給HttpServletResponse.sendRedirect方法的相對URL以」/」開頭,它是相對於整個WEB站點的根目錄;若是建立RequestDispatcher對象時指定的相對URL以」/」開頭,它是相對於當前WEB應用程序的根目錄。 【3】調用HttpServletResponse.sendRedirect方法重定向的訪問過程結束後,瀏覽器地址欄中顯示的URL會發生變化,由初始的URL地址變成重定向的目標URL;調用RequestDispatcher.forward方法的請求轉發過程結束後,瀏覽器地址欄保持初始的URL地址不變。 【4】HttpServletResponse.sendRedirect方法對瀏覽器的請求直接做出響應,響應的結果就是告訴瀏覽器去從新發出對另一個URL的訪問請求;RequestDispatcher.forward方法在服務器端內部將請求轉發給另一個資源,瀏覽器只知道發出了請求並獲得了響應結果,並不知道在服務器程序內部發生了轉發行爲。 【5】RequestDispatcher.forward方法的調用者與被調用者之間共享相同的request對象和response對象,它們屬於同一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的request對象和response對象,它們屬於兩個獨立的訪問請求和響應過程。

相關文章
相關標籤/搜索