HttpServletRequest對象表明客戶端的請求,當客戶端經過HTTP協議訪問服務器時,HTTP請求頭中的全部信息都封裝在這個對象中,經過這個對象提供的方法,能夠得到客戶端請求的全部信息。html
getRequestURL方法返回客戶端發出請求時的完整URL。
getRequestURI方法返回請求行中的資源名部分。
getQueryString 方法返回請求行中的參數部分。
getPathInfo方法返回請求URL中的額外路徑信息。額外路徑信息是請求URL中的位於Servlet的路徑以後和查詢參數以前的內容,它以「/」開頭。
getRemoteAddr方法返回發出請求的客戶機的IP地址。
getRemoteHost方法返回發出請求的客戶機的完整主機名。
getRemotePort方法返回客戶機所使用的網絡端口號。
getLocalAddr方法返回WEB服務器的IP地址。
getLocalName方法返回WEB服務器的主機名。java
範例:經過request對象獲取客戶端請求信息web
1 package gacl.request.study; 2 import java.io.IOException; 3 import java.io.PrintWriter; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 /** 9 * @author gacl 10 * 經過request對象獲取客戶端請求信息 11 */ 12 public class RequestDemo01 extends HttpServlet { 13 14 public void doGet(HttpServletRequest request, HttpServletResponse response) 15 throws ServletException, IOException { 16 /** 17 * 1.得到客戶機信息 18 */ 19 String requestUrl = request.getRequestURL().toString();//獲得請求的URL地址 20 String requestUri = request.getRequestURI();//獲得請求的資源 21 String queryString = request.getQueryString();//獲得請求的URL地址中附帶的參數 22 String remoteAddr = request.getRemoteAddr();//獲得來訪者的IP地址 23 String remoteHost = request.getRemoteHost(); 24 int remotePort = request.getRemotePort(); 25 String remoteUser = request.getRemoteUser(); 26 String method = request.getMethod();//獲得請求URL地址時使用的方法 27 String pathInfo = request.getPathInfo(); 28 String localAddr = request.getLocalAddr();//獲取WEB服務器的IP地址 29 String localName = request.getLocalName();//獲取WEB服務器的主機名 30 response.setCharacterEncoding("UTF-8");//設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 31 //經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,若是不加這句話,那麼瀏覽器顯示的將是亂碼 32 response.setHeader("content-type", "text/html;charset=UTF-8"); 33 PrintWriter out = response.getWriter(); 34 out.write("獲取到的客戶機信息以下:"); 35 out.write("<hr/>"); 36 out.write("請求的URL地址:"+requestUrl); 37 out.write("<br/>"); 38 out.write("請求的資源:"+requestUri); 39 out.write("<br/>"); 40 out.write("請求的URL地址中附帶的參數:"+queryString); 41 out.write("<br/>"); 42 out.write("來訪者的IP地址:"+remoteAddr); 43 out.write("<br/>"); 44 out.write("來訪者的主機名:"+remoteHost); 45 out.write("<br/>"); 46 out.write("使用的端口號:"+remotePort); 47 out.write("<br/>"); 48 out.write("remoteUser:"+remoteUser); 49 out.write("<br/>"); 50 out.write("請求使用的方法:"+method); 51 out.write("<br/>"); 52 out.write("pathInfo:"+pathInfo); 53 out.write("<br/>"); 54 out.write("localAddr:"+localAddr); 55 out.write("<br/>"); 56 out.write("localName:"+localName); 57 } 58 59 public void doPost(HttpServletRequest request, HttpServletResponse response) 60 throws ServletException, IOException { 61 doGet(request, response); 62 } 63 64 }
運行結果:編程
getHeader(string name)方法:String
getHeaders(String name)方法:Enumeration
getHeaderNames()方法 設計模式
範例:經過request對象獲取客戶端請求頭信息數組
1 package gacl.request.study; 2 import java.io.IOException; 3 import java.io.PrintWriter; 4 import java.util.Enumeration; 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 /** 10 * @author gacl 11 * 獲取客戶端請求頭信息 12 * 客戶端請求頭: 13 * 14 */ 15 public class RequestDemo02 extends HttpServlet { 16 17 public void doGet(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 response.setCharacterEncoding("UTF-8");//設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 20 //經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據 21 response.setHeader("content-type", "text/html;charset=UTF-8"); 22 PrintWriter out = response.getWriter(); 23 Enumeration<String> reqHeadInfos = request.getHeaderNames();//獲取全部的請求頭 24 out.write("獲取到的客戶端全部的請求頭信息以下:"); 25 out.write("<hr/>"); 26 while (reqHeadInfos.hasMoreElements()) { 27 String headName = (String) reqHeadInfos.nextElement(); 28 String headValue = request.getHeader(headName);//根據請求頭的名字獲取對應的請求頭的值 29 out.write(headName+":"+headValue); 30 out.write("<br/>"); 31 } 32 out.write("<br/>"); 33 out.write("獲取到的客戶端Accept-Encoding請求頭的值:"); 34 out.write("<hr/>"); 35 String value = request.getHeader("Accept-Encoding");//獲取Accept-Encoding請求頭對應的值 36 out.write(value); 37 38 Enumeration<String> e = request.getHeaders("Accept-Encoding"); 39 while (e.hasMoreElements()) { 40 String string = (String) e.nextElement(); 41 System.out.println(string); 42 } 43 } 44 45 public void doPost(HttpServletRequest request, HttpServletResponse response) 46 throws ServletException, IOException { 47 doGet(request, response); 48 } 49 50 }
運行結果以下:瀏覽器
好比如今有以下的form表單服務器
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 3 <html> 4 <head> 5 <title>Html的Form表單元素</title> 6 </head> 7 <fieldset style="width:500px;"> 8 <legend>Html的Form表單元素</legend> 9 <!--form表單的action屬性規定當提交表單時,向何處發送表單數據,method屬性指明表單的提交方式,分爲get和post,默認爲get--> 10 <form action="${pageContext.request.contextPath}/servlet/RequestDemo03" method="post"> 11 <!--輸入文本框,SIZE表示顯示長度,maxlength表示最多輸入長度--> 12 編 號(文本框): 13 <input type="text" name="userid" value="NO." size="2" maxlength="2"><br> 14 <!--輸入文本框,經過value指定其顯示的默認值--> 15 用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"><br> 16 <!--密碼框,其中全部輸入的內容都以密文的形式顯示--> 17 密 碼(密碼框): 18 <!-- 表示的是一個空格--> 19 <input type="password" name="userpass" value="請輸入密碼"><br> 20 <!--單選按鈕,經過checked指定默認選中,名稱必須同樣,其中value爲真正須要的內容--> 21 性 別(單選框): 22 <input type="radio" name="sex" value="男" checked>男 23 <input type="radio" name="sex" value="女">女<br> 24 <!--下拉列表框,經過<option>元素指定下拉的選項--> 25 部 門(下拉框): 26 <select name="dept"> 27 <option value="技術部">技術部</option> 28 <option value="銷售部" SELECTED>銷售部</option> 29 <option value="財務部">財務部</option> 30 </select><br> 31 <!--複選框,能夠同時選擇多個選項,名稱必須同樣,其中value爲真正須要的內容--> 32 興 趣(複選框): 33 <input type="checkbox" name="inst" value="唱歌">唱歌 34 <input type="checkbox" name="inst" value="游泳">游泳 35 <input type="checkbox" name="inst" value="跳舞">跳舞 36 <input type="checkbox" name="inst" value="編程" checked>編程 37 <input type="checkbox" name="inst" value="上網">上網 38 <br> 39 <!--大文本輸入框,寬度爲34列,高度爲5行--> 40 說 明(文本域): 41 <textarea name="note" cols="34" rows="5"> 42 </textarea> 43 <br> 44 <!--隱藏域,在頁面上沒法看到,專門用來傳遞參數或者保存參數--> 45 <input type="hidden" name="hiddenField" value="hiddenvalue"/> 46 <!--提交表單按鈕,當點擊提交後,全部填寫的表單內容都會被傳輸到服務器端--> 47 <input type="submit" value="提交(提交按鈕)"> 48 <!--重置表單按鈕,當點擊重置後,全部表單恢復原始顯示內容--> 49 <input type="reset" value="重置(重置按鈕)"> 50 </form> 51 <!--表單結束--> 52 </fieldset> 53 </body> 54 <!--完結標記--> 55 </html> 56 <!--完結標記-->
在Form表單中填寫數據,而後提交到RequestDemo03這個Servlet進行處理,填寫的表單數據以下:網絡
在服務器端使用getParameter方法和getParameterValues方法接收表單參數,代碼以下:框架
1 package gacl.request.study; 2 import java.io.IOException; 3 import java.text.MessageFormat; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 /** 9 * @author gacl 10 * 獲取客戶端經過Form表單提交上來的參數 11 */ 12 public class RequestDemo03 extends HttpServlet { 13 14 public void doGet(HttpServletRequest request, HttpServletResponse response) 15 throws ServletException, IOException { 16 //客戶端是以UTF-8編碼提交表單數據的,因此須要設置服務器端以UTF-8的編碼進行接收,不然對於中文數據就會產生亂碼 17 request.setCharacterEncoding("UTF-8"); 18 /** 19 * 編 號(文本框): 20 <input type="text" name="userid" value="NO." size="2" maxlength="2"> 21 */ 22 String userid = request.getParameter("userid");//獲取填寫的編號,userid是文本框的名字,<input type="text" name="userid"> 23 /** 24 * 用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"> 25 */ 26 String username = request.getParameter("username");//獲取填寫的用戶名 27 /** 28 * 密 碼(密碼框):<input type="password" name="userpass" value="請輸入密碼"> 29 */ 30 String userpass = request.getParameter("userpass");//獲取填寫的密碼 31 String sex = request.getParameter("sex");//獲取選中的性別 32 String dept = request.getParameter("dept");//獲取選中的部門 33 //獲取選中的興趣,由於能夠選中多個值,因此獲取到的值是一個字符串數組,所以須要使用getParameterValues方法來獲取 34 String[] insts = request.getParameterValues("inst"); 35 String note = request.getParameter("note");//獲取填寫的說明信息 36 String hiddenField = request.getParameter("hiddenField");//獲取隱藏域的內容 37 38 String instStr=""; 39 /** 40 * 獲取數組數據的技巧,能夠避免insts數組爲null時引起的空指針異常錯誤! 41 */ 42 for (int i = 0; insts!=null && i < insts.length; i++) { 43 if (i == insts.length-1) { 44 instStr+=insts[i]; 45 }else { 46 instStr+=insts[i]+","; 47 } 48 } 49 50 String htmlStr = "<table>" + 51 "<tr><td>填寫的編號:</td><td>{0}</td></tr>" + 52 "<tr><td>填寫的用戶名:</td><td>{1}</td></tr>" + 53 "<tr><td>填寫的密碼:</td><td>{2}</td></tr>" + 54 "<tr><td>選中的性別:</td><td>{3}</td></tr>" + 55 "<tr><td>選中的部門:</td><td>{4}</td></tr>" + 56 "<tr><td>選中的興趣:</td><td>{5}</td></tr>" + 57 "<tr><td>填寫的說明:</td><td>{6}</td></tr>" + 58 "<tr><td>隱藏域的內容:</td><td>{7}</td></tr>" + 59 "</table>"; 60 htmlStr = MessageFormat.format(htmlStr, userid,username,userpass,sex,dept,instStr,note,hiddenField); 61 62 response.setCharacterEncoding("UTF-8");//設置服務器端以UTF-8編碼輸出數據到客戶端 63 response.setContentType("text/html;charset=UTF-8");//設置客戶端瀏覽器以UTF-8編碼解析數據 64 response.getWriter().write(htmlStr);//輸出htmlStr裏面的內容到客戶端瀏覽器顯示 65 } 66 67 public void doPost(HttpServletRequest request, HttpServletResponse response) 68 throws ServletException, IOException { 69 doGet(request, response); 70 } 71 }
運行結果以下:
在服務器端使用getParameterNames方法接收表單參數,代碼以下:
1 Enumeration<String> paramNames = request.getParameterNames();//獲取全部的參數名 2 while (paramNames.hasMoreElements()) { 3 String name = paramNames.nextElement();//獲得參數名 4 String value = request.getParameter(name);//經過參數名獲取對應的值 5 System.out.println(MessageFormat.format("{0}={1}", name,value)); 6 }
運行結果以下:
在服務器端使用getParameterMap方法接收表單參數,代碼以下:
1 //request對象封裝的參數是以Map的形式存儲的 2 Map<String, String[]> paramMap = request.getParameterMap(); 3 for(Map.Entry<String, String[]> entry :paramMap.entrySet()){ 4 String paramName = entry.getKey(); 5 String paramValue = ""; 6 String[] paramValueArr = entry.getValue(); 7 for (int i = 0; paramValueArr!=null && i < paramValueArr.length; i++) { 8 if (i == paramValueArr.length-1) { 9 paramValue+=paramValueArr[i]; 10 }else { 11 paramValue+=paramValueArr[i]+","; 12 } 13 } 14 System.out.println(MessageFormat.format("{0}={1}", paramName,paramValue)); 15 }
運行結果以下:
例若有以下的form表單頁面:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>request接收中文參數亂碼問題</title> 7 </head> 8 9 <body> 10 <form action="<%=request.getContextPath()%>/servlet/RequestDemo04" method="post"> 11 用戶名:<input type="text" name="userName"/> 12 <input type="submit" value="post方式提交表單"> 13 </form> 14 </body> 15 </html>
此時在服務器端接收中文參數時就會出現中文亂碼,以下所示:
能夠看到,之因此會產生亂碼,就是由於服務器和客戶端溝通的編碼不一致形成的,所以解決的辦法是:在客戶端和服務器之間設置一個統一的編碼,以後就按照此編碼進行數據的傳輸和接收。
因爲客戶端是以UTF-8字符編碼將表單數據傳輸到服務器端的,所以服務器也須要設置以UTF-8字符編碼進行接收,要想完成此操做,服務器能夠直接使用從ServletRequest接口繼承而來的"setCharacterEncoding(charset)"方法進行統一的編碼設置。修改後的代碼以下:
1 public void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 /** 4 * 客戶端是以UTF-8編碼傳輸數據到服務器端的,因此須要設置服務器端以UTF-8的編碼進行接收,不然對於中文數據就會產生亂碼 5 */ 6 request.setCharacterEncoding("UTF-8"); 7 String userName = request.getParameter("userName"); 8 System.out.println("userName:"+userName); 9 }
使用request.setCharacterEncoding("UTF-8");設置服務器以UTF-8的編碼接收數據後,此時就不會產生中文亂碼問題了,以下所示:
例若有以下的form表單頁面:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>request接收中文參數亂碼問題</title> 7 </head> 8 9 <body> 10 <form action="${pageContext.request.contextPath}/servlet/RequestDemo04" method="get"> 11 姓名:<input type="text" name="name"/> 12 <input type="submit" value="get方式提交表單"> 13 </form> 14 </body> 15 </html>
此時在服務器端接收中文參數時就會出現中文亂碼,以下所示:
那麼這個中文亂碼問題又該如何解決呢,是否能夠經過request.setCharacterEncoding("UTF-8");設置服務器 以UTF-8的編碼進行接收這種方式來解決中文亂碼問題呢,注意,對於以get方式傳輸的中文數據,經過 request.setCharacterEncoding("UTF-8");這種方式是解決不了中文亂碼問題,以下所示:
對於以get方式傳輸的數據,request即便設置了以指定的編碼接收數據也是無效的(至於爲何無效我也沒有弄明白),默認的仍是使用 ISO8859-1這個字符編碼來接收數據,客戶端以UTF-8的編碼傳輸數據到服務器端,而服務器端的request對象使用的是ISO8859-1這 個字符編碼來接收數據,服務器和客戶端溝通的編碼不一致所以纔會產生中文亂碼的。解決辦法:在接收到數據後,先獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,而後經過字節數組以指定的編碼構建字符串,解決亂碼問題。代碼以下:
1 public void doGet(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 /** 4 * 5 * 對於以get方式傳輸的數據,request即便設置了以指定的編碼接收數據也是無效的,默認的仍是使用ISO8859-1這個字符編碼來接收數據 6 */ 7 String name = request.getParameter("name");//接收數據 8 name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;//獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,而後經過字節數組以指定的編碼構建字符串,解決亂碼問題 9 System.out.println("name:"+name); 10 }
運行結果以下:
客戶端想傳輸數據到服務器,能夠經過表單提交的形式,也能夠經過超連接後面加參數的形式,例如:
1 <a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=徐達沛">點擊</a>
點擊超連接,數據是以get的方式傳輸到服務器的,因此接收中文數據時也會產生中文亂碼問題,而解決中文亂碼問題的方式與上述的以get方式提交表單中文數據亂碼處理問題的方式一致,以下所示:
1 String name = request.getParameter("name"); 2 name =new String(name.getBytes("ISO8859-1"), "UTF-8");
另外,須要提的一點就是URL地址後面若是跟了中文數據,那麼中文參數最好使用URL編碼進行處理,以下所示:
1 <a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=<%=URLEncoder.encode("徐達沛", "UTF-8")%>">點擊</a>
一、若是提交方式爲post,想不亂碼,只須要在服務器端設置request對象的編碼便可,客戶端以哪一種編碼提交的,服務器端的request對象就以對應的編碼接收,好比客戶端是以UTF-8編碼提交的,那麼服務器端request對象就以UTF-8編碼接收(request.setCharacterEncoding("UTF-8"))
二、若是提交方式爲get,設置request對象的編碼是無效的,request對象仍是以默認的ISO8859-1編碼接收數據,所以要想不亂碼,只能在接收到數據後再手工轉換,步驟以下:
1).獲取獲取客戶端提交上來的數據,獲得的是亂碼字符串,data="???è?????"
String data = request.getParameter("paramName");
2).查找ISO8859-1碼錶,獲得客戶機提交的原始數據的字節數組
byte[] source = data.getBytes("ISO8859-1");
3).經過字節數組以指定的編碼構建字符串,解決亂碼
data = new String(source, "UTF-8");
經過字節數組以指定的編碼構建字符串,這裏指定的編碼是根據客戶端那邊提交數據時使用的字符編碼來定的,若是是GB2312,那麼就設置成data = new String(source, "GB2312"),若是是UTF-8,那麼就設置成data = new String(source, "UTF-8")
請求轉發:指一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理。
請求轉發的應用場景:MVC設計模式
在Servlet中實現請求轉發的兩種方式:
一、經過ServletContext的getRequestDispatcher(String path)方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法能夠實現請求轉發。
例如:將請求轉發的test.jsp頁面
1 RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp"); 2 reqDispatcher.forward(request, response);
二、經過request對象提供的getRequestDispatche(String path)方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法能夠實現請求轉發。
例如:將請求轉發的test.jsp頁面
1 request.getRequestDispatcher("/test.jsp").forward(request, response);
request對象同時也是一個域對象(Map容器),開發人員經過request對象在實現轉發時,把數據經過request對象帶給其它web資源處理。
例如:請求RequestDemo06 Servlet,RequestDemo06將請求轉發到test.jsp頁面
1 package gacl.request.study; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class RequestDemo06 extends HttpServlet { 10 11 public void doGet(HttpServletRequest request, HttpServletResponse response) 12 throws ServletException, IOException { 13 14 String data="你們好,我是孤傲蒼狼,我正在總結JavaWeb"; 15 /** 16 * 將數據存放到request對象中,此時把request對象看成一個Map容器來使用 17 */ 18 request.setAttribute("data", data); 19 //客戶端訪問RequestDemo06這個Servlet後,RequestDemo06通知服務器將請求轉發(forward)到test.jsp頁面進行處理 20 request.getRequestDispatcher("/test.jsp").forward(request, response); 21 } 22 23 public void doPost(HttpServletRequest request, HttpServletResponse response) 24 throws ServletException, IOException { 25 doGet(request, response); 26 } 27 }
test.jsp頁面代碼以下:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>Request對象實現請求轉發</title> 7 </head> 8 9 <body> 10 使用普通方式取出存儲在request對象中的數據: 11 <h3 style="color:red;"><%=(String)request.getAttribute("data")%></h3> 12 使用EL表達式取出存儲在request對象中的數據: 13 <h3 style="color:red;">${data}</h3> 14 </body> 15 </html>
運行結果以下:
request對象做爲一個域對象(Map容器)使用時,主要是經過如下的四個方法來操做
一個web資源收到客戶端請求後,通知服務器去調用另一個web資源進行處理,稱之爲請求轉發/307。
一個web資源收到客戶端請求後,通知瀏覽器去訪問另一個web資源進行處理,稱之爲請求重定向/302。