生活随笔
收集整理的這篇文章主要介紹了
大数据WEB阶段(九)Servlet+Request
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Servlet與Request
一、概述
Servlet
是sun公司提供的一門用于開發動態web資源的技術按照這套規范寫出來的servlet可以放置在web應用中在servlet容器中運行 。 開發servlet步驟
寫一個類實現servlet接口 , 并實現其中的方法在web.xml中為servlet配置對外訪問路徑案例:
手寫一個servlet:1.在指定位置(如D盤)創建一個FirstServlet.java文件, 創建FirstServlet類, 繼承GenericServlet類public class FirstServlet extends GenericServlet{}2.添加未實現的service方法, 實現內部代碼public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException{String dateStr = new Date().toLocaleString();res.getWriter().write(dateStr);}3.添加包結構, 并導入依賴包package cn.servlet;import java.util.*;import java.io.*;import javax.servlet.*;4.編譯Servlet類在編譯之前, 找到 [tomcat7.0]\lib\servlet-api.jar 包, 在cmd窗口中將其所在路徑設置給classpath如: set classpath=E:\software\tomcat7.0\lib\servlet-api.jar帶包編譯:進入到FirstServlet.java所在路徑命令: javac -d . FirstServlet.java 其中: -d是帶包編譯點(.)表示編譯后的class存放在當前目錄下5.將編譯的class所在的整個目錄放在WEB應用下的/WEB-INF/classes目錄下6.在web.xml中配置Servlet對外訪問的虛擬路徑<servlet><servlet-name>FirstServlet</servlet-name><servlet-class>cn.servlet.FirstServlet</servlet-class></servlet><servlet-mapping><servlet-name>FirstServlet</servlet-name><url-pattern>/FirstServlet</url-pattern></servlet-mapping>7.將WEB應用配置到tomcat服務器中, 并啟動服務器訪問如下路徑來訪問FirstServlethttp://localhost/news/servlet/FirstServlet
二、使用myeclipse開發servlet
使用myeclipse開發servlet程序時 , 可以新建一個servlet , 默認繼承HttpServlet , 在Servlet內部會覆蓋doGet()和 doPost()方法 , 分別來處理GET請求和POST請求 。新建項目
新建一個web project, 給設置一個項目名稱 ,一般其他保持默認即可 , 然后finish , 彈出的對話框選擇yes即可。新建一個Servlet
新建一個servlet , 如果new中找不到servlet , 注意視圖是否換到MyEclipse中 , 給一個包名和類名 , 下面對勾只留doGet()和doPost(),其他去掉 , 下一步這里將最后兩行刪掉,是一些xml中的提示,其他地方一般保持默認即可,也可以修改對外訪問路徑,其中name和URL會自動配置到xml中。最后finash。一些疑問
為什么要繼承HttpServlet?
因為這是一個繼承了GenericServlet的類,已經提供doGet()和doPost()方法,可以方便我們開發web項目。而GenericServlet是一個基礎的實現,如果要用此類,需要自己寫doGet()和doPost()方法,并且需要在service方法中對請求進行判斷,會比較麻煩。 HttpServlet底層又是如何實現的?
可以打開HttpServlet源碼,發現HttpServlet也是繼承自GenericServlet,同時,HttpServlet會寫各種方法,比如doGet()和doPost(),然后在service方法中進行判斷,不同的請求調用不同的方法。注意:
復制一個servlet之后 , web.xml文件中不會自動生成配置文件 ,, 所以一般不要復制 , 直接新建 。 在myeclipse配置tomcat ,并將項目發布到tomcat中
查看http://blog.csdn.net/chou_out_man/article/details/78700153
三、Servlet繼承結構
四、修改servlet模板
方式一:
下載http://dl.download.csdn.net/down11/20171203/44e21f5d54727c09ffa2214f7427287b.jar?response-content-disposition=attachment%3Bfilename%3D%22com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar%22&OSSAccessKeyId=9q6nvzoJGowBj4q1&Expires=1512269518&Signature=J1sMRCVX4mp3WUiO%2FO2%2BloDU52U%3D&user=chou_out_man&sourceid=10142677拷貝到【MyEclipse安裝目錄】\Common\pligins目錄下 , 會提示是否替換文件 , 確定提換即可 , 如果沒有提示 , 則有可能進錯目錄了方式二:
在【MyEclipse安裝目錄】\Common\pligins目錄下找到文件:com.(1)genuitec.eclipse.wizards.xxx.jar,在此文件中的Templates目錄下可以看到Servlet.java源代碼。打開源代碼 , 將doGet()和doPost()兩個方法的注釋和方法中的內容刪掉即可修改之后保存重啟MyEclipse后新建servlet即可看到效果 。
五、Servlet調用過程
調用過程
Servlet生命周期
Servlet實例在第一次被訪問時創建, 創建之后服務器會立即調用init方法進行初始化的操作, 從此以后該實例會一直駐留在服務器的內存中, 為后續的請求服務, 只要有請求訪問servlet, 服務器就會調用service方法來處理這個請求, 直到服務器關閉或者是web應用被移出容器時為止, 隨著web應用的銷毀, servlet實例也會跟著銷毀, 在銷毀之前, 服務器就調用destroy方法進行善后的處理.
六、servlet虛擬路徑
在web.xml文件中可以配置對外訪問的虛擬路徑 , 可以直接寫一個路徑或者通過通配符*號寫一個路徑
1. 方式一:直接寫一個路徑
/servlet/dotestservlet
2. 方式二:通過通配符*號寫一個路徑
1. 以 / 開頭, 以 /* 結尾
如: /servlet/* /a/* /*
2. 以 *.后綴 的形式, 如: *.html *.servlet *.do *.action
3. 使用*號匹配符寫路徑, 路徑的配置變得更加靈活, 但是也可能會造成, 一個url會被多個servlet Mapping所匹配 , 如:Url:http://localhost/day09/servlet/SecondServlet.doServlet1:Test1: /servlet/*Servlet2:Test2: *.do
4. 匹配規則:1. *.后綴的優先級永遠最低2. 哪一個最接近哪一個起作用3. 示例:Servlet1 映射到 /abc/* Servlet2 映射到 /* Servlet3 映射到 /abc Servlet4 映射到 *.do 當請求URL為“/abc/a.html”,“/abc/*”和“/*”都匹配,哪個servlet響應Servlet引擎將調用Servlet1。當請求URL為“/abc”時,“/abc/*”和“/abc”都匹配,哪個servlet響應Servlet引擎將調用Servlet3。當請求URL為“/abc/a.do”時,“/abc/*”和“*.do”都匹配,哪個servlet響應Servlet引擎將調用Servlet1。當請求URL為“/a.do”時,“/*”和“*.do”都匹配,哪個servlet響應Servlet引擎將調用Servlet2。
七、Request
代表HTTP請求的對象繼承結構
request功能
獲取客戶端相關信息
getRequestURL方法 – 返回客戶端發出請求完整URL
如: http://localhost/day09/servlet/SecondServlet
getRequestURI方法 – 返回請求行中的資源名部分
如: /day09/servlet/SecondServlet
getQueryString方法 – 返回請求行中的參數部分
如: username=zhangfei&password=123
getRemoteAddr方法 – 返回發出請求的客戶機的IP地址
如: 127.0.0.1 //可能會出現0:0:0:0:0:0:0:1形式,是ipv6的表現形式。
getMethod – 得到客戶機請求方式
如: GET或POST
getContextPath – 獲得當前web應用虛擬目錄名稱
如: /day09
注意:在寫路徑時不要將web應用的虛擬路徑的名稱寫死, 應該在需要寫web應用的名稱的地方通過getContextPath方法動態獲取獲取請求頭信息
getHeader(name)方法 –String getHeaders(String name)方法 — Enumeration
可以通過遍歷枚舉遍歷每一個信息
例如:while (values.hasMoreElements()) {String value = (String) values.nextElement();System.out.println(value);
}
getHeaderNames方法 — EnumerationgetIntHeader(name)方法 — intgetDateHeader(name)方法 — long(日期對應毫秒)獲取請求參數
getParameter(String name) — String 通過name獲得值getParameterValues(String name) — String[ ] 通過name獲得多值 checkboxgetParameterMap() — Map key :name value: 多值getParameterNames() — Enumeration 獲得所有name請求參數時的亂碼問題
亂碼分析: 編碼和解碼時使用的 碼表不一致造成的 。 編碼是在瀏覽器中進行的 , 瀏覽器打開頁面時使用的是什么碼表 ,在發送數據時使用的也是相同的碼表 。 解碼在服務器端進行 , 如果不指定解碼時使用的碼表 , 則默認使用ISO-8859-1解決方案: 在服務器解碼前 , 通知服務器解碼時應該使用的碼表。使瀏覽器編碼和服務器解碼時的碼表一致 。 Post方式提交參數的解決方案:
request.setCharacterEnCoding("utf-8");//用來通知服務器使用什么編碼來接受請求實體內容中的數據, 如果使用的是POST提交, POST提交的請求參數就是在請求實體內容中!, 所有這個方法可以解決POST提交的亂碼問題!!!
Get方式提交參數的解決方案
GET提交的請求參數由于不在請求實體內容中,而是在請求行中的請求資源路徑后面拼接著, 所以這行代碼對GET提交的參數亂碼不起作用!!! GET提交的亂碼問題可以通過手動編解碼來解決!!//>>username為亂碼, 通過亂碼反向編碼得回二進制數組byte[] bytes = username.getBytes("iso8859-1");//>>通過二進制數組查詢正確的碼表, 得出正確的數據username = new String(bytes, "utf-8");
實現請求轉發
請求重定向: 302狀態碼+Location響應頭請求轉發: 與請求重定向都可以實現資源的跳轉 , 但是區別是 :請求轉發是服務器內部的并且是同一web應用內部的跳轉 , 而重定向的資源跳轉沒有限制 。 請求轉發的特點:
一次請求一次響應 。 地址欄不會發生變化轉發被限制在同一個web應用中實現代碼
創建servlet:RequestDemo3和RequestDemo4,RequestDemo3轉發到RequestDemo4在RequestDemo3中:
/** 在web階段寫路徑時,除了請求轉發和請求包含在寫* 路徑是不用包含web應用的虛擬路徑,其他地方都需要* 加上web應用的虛擬路徑。* 完整路徑:http://localhost/day09/servlet/RequestDemo4*/request.getRequestDispatcher("/servlet/RequestDemo4").forward(request, response);在RequestDemo4中響應:response.getWriter().write("1$");
request開發細節:
在轉發之前, 如果response緩沖區被寫入了數據但是還沒有打給瀏覽器, 在轉發時response緩沖區(數據)將會被清空!
例如:在RequestDemo3中添加代碼:
response.getWriter().write("no money!");
發現瀏覽器中并未得到"no money!"這段字符串的響應。在轉發之前, 如果response緩沖區被寫入了數據并且已經打給了瀏覽器, 轉發將會失敗!!
例如:在RequestDemo3中添加代碼:
response.getWriter().write("no money!");response.flushBuffer();
發現瀏覽器可以顯示"no money!",因為強制刷新了,但是轉發就會報錯,因為已經響應過了,一次請求對應一次響應。在同一個Servlet中轉發不能進行多次!!(A既轉發B, 又轉發給C)但是可以進行多重轉發(比如A轉發給B, B再轉發給C)
作為域對象來使用
域對象: 一個對象具有一個可被看見的范圍 , 并且利用該對象上的map可以在整個范圍內實現資源的共享域對象提供的方法(可以操作map中的數據)
setAttribute(String name,Object value) :用來存儲一個對象,也可以稱之為存儲一個域屬性getAttribute(String name); 用來獲取request中的數據removeAttribute(String name); 用來移除request中的域屬性getAttributeNames(); 獲取所有域屬性的名稱域對象生命周期
請求開始時創建 , 請求結束時死亡作用范圍: 一次請求鏈主要功能:
在作用范圍內共享數據實現請求包含
請求包含是服務器中內部資源合并的現象如果瀏覽器請求ServletA , 但是A不能獨立完成處理這個請求 , 需要另外一個ServletB幫忙 , 于是在A中可以將B包含進來 ,包含進來之后將由A和B共同處理這次請求 , 處理的結果也將合并在一起 , 一同發送給瀏覽器 。 如:
request.getRequestDispatcher(“B的路徑”).include(request, response);
總結
以上是生活随笔為你收集整理的大数据WEB阶段(九)Servlet+Request的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。