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對象,它們屬於兩個獨立的訪問請求和響應過程。