一、HttpServletRequest概述
1.1、HttpServletRequest簡介
二、詳解HttpServletRequest
2.1、請求行
// getMethod(); 獲得請求方式 // ***getRequestURL();返回客戶端發出請求時的完整URL。 // ***getRequestURI(); 返回請求行中的資源名部分。 // *****getContextPath(); 當前應用的虛擬目錄 /day09_01_HttpServletRequest // getQueryString() ; 返回請求行中的參數部分。 System.out.println(request.getMethod());// GET System.out.println(request.getRequestURL()); // http://localhost:8080/day09_01_HttpServletRequest/servlet/demo1 System.out.println(request.getRequestURI()); // /day09_01_HttpServletRequest/servlet/demo1 System.out.println(request.getContextPath()); // /day09_01_HttpServletRequest System.out.println(request.getQueryString()); // username=tom
舉例二:Get http://localhost:6060/Web_Servlet/ServletTest3?username=faker&password=mid http/1.1
相關方法:
getRequestURI();
getRequestURL();
getProtocol();
getScheme();
getServerName();
getServerPort();
getContextPath();
getServletPath();
getQueryString();
getRemoteAddr();
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.統一資源標記符 /Web_Servlet/ServletTest3 String uri = req.getRequestURI(); System.out.println(uri); //2.統一資源定位符 http://localhost:6060/Web_Servlet/ServletTest3 StringBuffer url = req.getRequestURL(); System.out.println(url); //3.協議和版本 HTTP/1.1 String potocol = req.getProtocol(); System.out.println(potocol); //4.協議 http String scheme = req.getScheme(); System.out.println(scheme); //5.主機(域名) localhost,如果你使用的是ip地址,就顯示ip地址 String serverName = req.getServerName(); System.out.println(serverName); //6.端口 6060(這是我自己修改了的端口,默認是8080) int port = req. getServerPort(); System.out.println(port); //7.發布到tomcat下的項目名稱 /Web_Servlet String contextPath = req.getContextPath(); System.out.println(contextPath); //8.servlet路徑 /ServletTest3 String servletPath = req.getServletPath(); System.out.println(servletPath); //9.獲取所有請求參數,即?之后所有東西。 username=faker&password=mid String queryString = req.getQueryString(); System.out.println(queryString); //10.遠程主機的ip地址 0:0:0:0:0:0:0:1 String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); }
2.2、請求頭
我們可以查看任意一個網頁,它都是有請求頭的。

相關方法:
String getHeader(String name) 根據頭名稱得到頭信息值
long getDateHeader(java.lang.String name) 獲得指定頭內容Date
int getIntHeader(java.lang.String name) 獲得指定頭內容int
Enumeration getHeaderNames() 得到所有頭信息name
Enumeration getHeaders(String name) 根據頭名稱得到相同名稱頭信息值
舉例1:Enumeration getHeaderNames() 得到所有頭信息name
Enumeration<String> headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()){ String key = (String)headerNames.nextElement(); String value = req.getHeader(key); System.out.println(key+"="+value); }
結果:

舉例2:Enumeration getHeaders(String name) 根據頭名稱得到相同名稱頭信息值
Enumeration<String> headers = req.getHeaders("accept-language"); while(headers.hasMoreElements()){ String key = (String)headers.nextElement(); String value = req.getHeader(key); System.out.println(key+"==="+value); }
結果:

2.3、請求體(請求正文)
1)與表單獲取相關的方法
方法:
String getParameter(name) 根據表單中name屬性的名,獲取value屬性的值方法
String[] getParameterValues(String name) 專為復選框取取提供的方法
getParameterNames() 得到表單提交的所有name的方法
Map<String , String[]> getParameterMap() 得到表單提交的所有值的方法 //做框架用,非常實用
getInputStream 以字節流的方式得到所有表單數據
舉例:
<form action="/day09_01_HttpServletRequest/servlet/demo3" method="get"> 用戶名:<input type="text" name="userName"/><br/> 密碼:<input type="password" name="pwd"/><br/> 性別:<input type="radio" name="sex" value="男" checked="checked"/>男 <input type="radio" name="sex" value="女"/>女 <br/> 愛好 : <input type="checkbox" name="hobby" value="籃球"/>籃球 <input type="checkbox" name="hobby" value="唱歌"/>唱歌 <input type="checkbox" name="hobby" value="編碼"/>編碼 <br/> 所在城市: <select name="city"> <option>------請選擇------</option> <option value="bj">北京</option> <option value="sh">上海</option> <option value="gz">廣州</option> </select> <br/> <input type="submit" value="注冊"/> </form>
測試1使用方法:
//獲取表單數據 //根據表單中name屬性的名,獲取value屬性的值方法 String userName = request.getParameter("userName"); String pwd = request.getParameter("pwd"); String sex = request.getParameter("sex"); String[] hobbys = request.getParameterValues("hobby"); String city = request.getParameter("city"); userName = new String(userName.getBytes("iso-8859-1"),"UTF-8"); System.out.println(userName); System.out.println(pwd); System.out.println(sex); for (int i = 0;hobbys!=null && i < hobbys.length; i++) { System.out.print(hobbys[i]+"\t"); } System.out.println(); System.out.println(city);
測試2使用方法:
getParameterNames() 得到表單提交的所有name的方法
getParameterValues(String name)專業為復選框取取提供的方法
//獲取所有的表單name的名子 Enumeration names = request.getParameterNames(); while(names.hasMoreElements()){ String name = (String) names.nextElement();//得到每一個name名 String[] values = request.getParameterValues(name);//根據name名,得到value值 for (int i = 0;values!=null && i < values.length; i++) { System.out.println(name+"\t"+values[i]);
測試3使用方法:
getParameterMap 到表單提交的所有值的方法 //做框架用,非常實用
try { User u = new User(); System.out.println("封裝數據前:"+u); //獲取表單數據 Map<String,String[]> map = request.getParameterMap(); for (Map.Entry<String, String[]> m : map.entrySet()) { String name = m.getKey(); String[] value = m.getValue(); //創建一屬性描述器 PropertyDescriptor pd = new PropertyDescriptor(name, User.class); //得到setter屬性 Method setter = pd.getWriteMethod(); if(value.length==1){ setter.invoke(u, value[0]);//給一個值的變量賦值 }else{ setter.invoke(u, (Object)value);//相關於給復選框賦值 } } System.out.println("封裝數據后:"+u); } catch (Exception e) { e.printStackTrace(); }
測試4使用方法:
getInputStream 以字節流的方式得到所有表單數據
request.setCharacterEncoding("UTF-8"); //獲取表單數據 ServletInputStream sis = request.getInputStream(); int len = 0; byte[] b = new byte[1024]; while((len=sis.read(b))!=-1){ //System.out.println(new String(new String(b,0,len).getBytes(),"utf-8")); System.out.println(new String(b, 0, len, "UTF-8")); } sis.close();
2)與操作非表單數據相關的方法(request也是一個域對象)
方法:
void setAttribute(String name, Object value);
Object getAttribute(String name);
Void removeAttribute(String name);
3)與請求轉發相關的方法
方法:
//得到請求轉發或請求包含的協助對象
RequestDispatcher getRequestDispatcher(String path)
forward(ServletRequest request, ServletResponse response) //轉發的方法
include(ServletRequest request, ServletResponse response) //請求包含
注意:
include()方法的處理流程:
一是:如果目標組件為Servlet或JSP,就執行它們,並把它們產生的響應正文添加到源組件的響應結果中;
如果目標組件為HTML文檔,就直接把文檔的內容添加到源組件的響應結果中。
二是:返回到源組件的服務方法中,繼續執行后續代碼塊。
特點:
一是:源組件與被包含的目標組件的輸出數據都會被添加到響應結果中。
二是:在目標組件中對響應狀態代碼或者響應頭所做的修改都會被忽略。
使用:
//path:轉發后跳轉的頁面,這里不管用不用"/"開頭,都是以web項目根開始,因為這是請求轉發,請求轉發只局限與在同一個web項目下使用,所以這里一直都是從web項目根下開始的。
request.getRequestDispatcher(String path).forward(request,response);
web項目根:
開發:G:\Workspaces\test01\WebRoot\..
運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\test01\..
web站點根:
運行時:D:\java\tomcat\apache-tomcat-7.0.53\webapps\..
從這里可以看出,web項目根就是從該web項目名開始,所以我們請求轉發時,只需要接着項目名后面需要訪問的路徑寫就行了。
特點:瀏覽器中url不會改變,也就是瀏覽器不知道服務器做了什么,是服務器幫我們跳轉頁面的,並且在轉發后的頁面,能夠繼續使用原先的request,因為是原先的request,所以request域中的屬性都可以繼續獲取到。
4)與編碼相關的方法
三、reqeust的常見應用
3.1、各種表單輸入項數據的獲取
3.2、request對象實現請求轉發
請求轉發指一個web資源收到客戶端請求后,通知服務器去調用另外一個web資源進行處理。
request對象提供了一個getRequestDispatcher方法,該方法返回一個RequestDispatcher對象,調用這個對象的forward方法可以實現請求轉發。
request對象同時也是一個域對象,開發人員通過request對象在實現轉發時,把數據通過request對象帶給其它web資源處理。
四、HttpServletResponse概述
4.1、HttpServletResponse簡介
4.2、HttpServletResponse細節
getOutputStream和getWriter方法分別用於得到輸出二進制數據、輸出文本數據的ServletOuputStream、Printwriter對象。
getOutputStream和getWriter這兩個方法互相排斥,調用了其中的任何一個方法后,就不能再調用另一方法。 會拋異常。
Servlet程序向ServletOutputStream或PrintWriter對象中寫入的數據將被Servlet引擎從response里面獲取,Servlet引擎將這些數據當作響應消息的正文,
然后再與響應狀態行和各響應頭組合后輸出到客戶端。
Serlvet的service方法結束后,Servlet引擎將檢查getWriter或getOutputStream方法返回的輸出流對象是否已經調用過close方法,
如果沒有,Servlet引擎將調用close方法關閉該輸出流對象。
五、詳解HttpServletResponse
5.1、響應行
響應狀態行 HTTP/1.1 200 OK
常見的響應狀態碼:
5.2、響應頭
Accept:指示HTTP響應可以接收的文檔類型集 Accept-Charset:告知客戶可以接收的字符集 Accept-Encoding:所有響應的字符編碼集 Content-Type:響應體的MIME類型 Content-Language:響應體的語言類型 Content-Length:響應體的長度和字節數 Expires:通知客戶端過期時間,防止客戶瀏覽器使用本地緩存副本 Cookie:包含保存到客戶端的Cookie集 Redirect:提供指定重定向,可以不向瀏覽器輸出響應內容,而是直接重新請求到另一個URL地址,實現重定向響應,即是一種自動定向。
//告知瀏覽器使用什么碼表 response.setHeader("content-type", "text/html;charset=UTF-8"); 代替了: //告訴服務器應用使用UTF-8解析文本 response.setCharacterEncoding("UTF-8"); //告訴客戶端要使用什么編碼 response.setHeader("content-type", "text/html;charset=UTF-8");
5.3、響應正文
常用方法:
getWrite(); 字符輸出流
getOutputStream(); 字節輸出流
setCharacterEncoding(String charset) 告知服務器使用什么編碼
setContentType(String type)
5.4、重定向
1)重定向運行原理
重定向機制的運作流程
第一步:用戶在瀏覽器端輸入特定URL,請求訪問服務器端的某個組件
第二步:服務器端的組件返回一個狀態碼為302的響應結果。
第三步:當瀏覽器端接收到這種響應結果后,再立即自動請求訪問另一個web組件
第四步:瀏覽器端接收到來自另一個web組件的響應結果。
HttpServeltResponse的sendRedirect(String location)用於重定向
2)具體實現
方式一:手動方案
response.setStatus(302); //狀態碼302就代表重定向
response.setHeader("location","http://www.baidu.com");
方式二:使用封裝好的,通過response.sendRedirect("http://www.baidu.com");
特點:服務器告訴瀏覽器要跳轉的頁面,是瀏覽器主動去跳轉的頁面,瀏覽器知道,也瀏覽器的地址欄中url會變,是瀏覽器重新發起一個請求到另外一個頁面,所以request是重新發起的,跟請求轉發不一樣。
注意:response.sendRedirect(path); //
第一種:response.sendRedirect("/test01/MyServlet01"); //使用了"/"開頭,說明是從web站點根開始,所以需要寫test01/MyServlet01
第二種:response.sendRedirect("MyServlet01"); //沒有使用"/"開頭,說明是從web項目根開始,那么就無需寫test01了。
注意:重定向沒有任何局限,可以重定向web項目內的任何路徑,也可以訪問別的web項目中的路徑,並且這里就用"/"區分開來,如果使用了"/"開頭,就說明我要重新開始定位了,不訪問剛才的web項目,自己寫項目名,
如果沒有使用"/"開始,那么就知道是訪問剛才那個web項目下的servlet,就可以省略項目名了。就是這樣來區別。
六、Response常見應用
6.1、向客戶端輸出中文數據
6.2、文件下載
//通過路徑得到一個輸入流 String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg"); FileInputStream fis = new FileInputStream(path); //創建字節輸出流 ServletOutputStream sos = response.getOutputStream(); //得到要下載的文件名 String filename = path.substring(path.lastIndexOf("\\")+1); //設置文件名的編碼 filename = URLEncoder.encode(filename, "UTF-8");//將不安全的文件名改為UTF-8格式 //告知客戶端要下載文件 response.setHeader("content-disposition", "attachment;filename="+filename); response.setHeader("content-type", "image/jpeg"); //執行輸出操作 int len = 1; byte[] b = new byte[1024]; while((len=fis.read(b))!=-1){ sos.write(b,0,len); } sos.close(); fis.close();
6.3、生成驗證碼
6.4、定時刷新頁面

喜歡就點個“推薦”哦!
