Servlet基礎教程
目錄
Servlet簡介
Java Servlet 是執行在 Web 伺服器或應用伺服器上的程式,它是作為來自 Web 瀏覽器或其他 HTTP 客戶端的請求和 HTTP 伺服器上的資料庫或應用程式之間的中間層。使用 Servlet,您可以收集來自網頁表單的使用者輸入,呈現來自資料庫或者其他源的記錄,還可以動態建立網頁。
1、Servlet的生命週期
Servlet 的生命週期可分為:例項化,初始化,就緒,銷燬。
init(): 在Servlet的生命週期中,僅執行一次init()方法。它是在伺服器裝入Servlet時執行的,負責初始化Servlet物件。可以配置伺服器,以在啟動伺服器或客戶機首次訪問Servlet時裝入Servlet。無論有多少客戶機訪問Servlet,都不會重複執行init()。
service(): 它是Servlet的核心,負責響應客戶的請求。每當一個客戶請求一個HttpServlet物件,該物件的Service()方法就要呼叫,而且傳遞給這個方法一個“請求”(ServletRequest)物件和一個“響應”(ServletResponse)物件作為引數。在HttpServlet中已存在Service()方法。預設的服務功能是呼叫與HTTP請求的方法相應的do功能。
destroy(): 僅執行一次,在伺服器端停止且解除安裝Servlet時執行該方法。當Servlet物件退出生命週期時,負責釋放佔用的資源。一個Servlet在執行service()方法時可能會產生其他的執行緒,因此需要確認在呼叫destroy()方法時,這些執行緒已經終止或完成。Servlet的工作過程
階段1:例項化 即容器呼叫構造器建立Servlet物件. 時機1:容器收到請求後,建立Servlet物件 時機2:容器啟動後,立即建立Servlet物件 web.xml中需要配置 <load-on-startup>1</load-on-startup> 階段2:初始化 容器在建立Servlet物件後,會立即呼叫init方法進行物件的初始化。一般情況下,我們不需要重寫此方法,因為父型別GenericServlet裡提供了init方法的實現邏輯。此方法儲存了另外一個物件ServletConfig的引用,如果你想初始化一些自定義的屬性,我們可以將初始化的值配置在web.xml裡。
<init-param> <param-name>company</param-name> <param-value>華育興業</param-value> </init-param>
通過ServletConfig提供的 getInitParameter(String name)來獲取值
public void init() throws ServletException { System.out.println("----初始化"); ServletConfig config = getServletConfig(); String company = config.getInitParameter("company"); }
階段3:就緒 初始化之後,容器呼叫Servlet物件的service方法進行資源分配。階段4:銷燬 容器會根據自己的演算法來進行Servlet物件的銷燬,銷燬前一定會呼叫destroy()方法。因此我們可以重寫此方法來完成一些業務邏輯。解除安裝程式時,一定會銷燬Servlet物件
public void destroy() { System.out.println("程式解除安裝了"); }
練習程式碼:
public class HelloServlet extends HttpServlet{
private String company;
private String manager;
public HelloServlet() {
System.out.println("建立servlet物件");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("處理業務邏輯");
System.out.println("company:"+company);
System.out.println("manager:"+manager);
}
@Override
public void init() throws ServletException {
System.out.println("----初始化");
ServletConfig config = getServletConfig();
company = config.getInitParameter("company");
manager = config.getInitParameter("manager");
}
@Override
public void destroy() {
System.out.println("程式解除安裝了");
}
}
2、Servlet的執行原理
- 瀏覽器依據IP和PORT與伺服器建立連線
- 傳送請求資料包到伺服器
- 伺服器建立Servlet元件物件
- 使用HttpServletRequest處理請求資料包(讀取頁面上的資料)
- 使用HttpServletResponse封裝響應資料(將程式中的資料傳送到頁面上)
- 伺服器傳送響應資料包
- 瀏覽器進行解析,生成頁面
Servlet的組織結構
appName ---》WEB-INF ---》classes ---》xxx.class檔案 ---》lib(可選) ---》web.xml ---》index.html(可選)
3、Servlet處理HTTP協議/請求方式
Servlet處理引數值
Servlet處理頁面上出入的值request呼叫下面方法
處理1:1形式的引數與引數值 String getParameter(String name) 如果name不存在,返回null 處理1:M形式的引數與引數值 String[] getParameterValues(String name) 如果name不存在,返回null
Servlet如何處理HTTP協議
當瀏覽器向伺服器端傳送請求後,伺服器端會維護兩個物件,用來封裝和處理請求資料包的資料,及其響應資料。分別是HttpServletRequest和HttpServletResponse物件 1、HttpServletRequest物件封裝和處理請求資料包的資料(接收頁面發來的資料) 提供了以下方法 String getParameter(String name) String[] getParameterValues(String name) String getHeader(String str) Enumration<E> getHeaders() RequestDispatcher getRequestDispatcher(String url) ....... 2、HttpServletResponse物件封裝和處理服務端要響應給瀏覽器的資料(將封裝好的資料傳送給瀏覽器) 提供了以下方法 void setContentType(String str) void sendRedirect(String url) .......
請求方式
瀏覽器向伺服器傳送請求的種類有八種: GET,POST,OPTIONS,HEAD,PUT,DELETE,TRACE,CONNECT (1)常用的兩種get和post get:向特定資源傳送請求(如返回登陸介面),在位址列上直接寫地址,表單的預設提交 post:向指定資源提交資料(提交表單,上傳檔案),要想使用此種方式提交,表單的method屬性設定POST (2)兩者的區別 get:提交的資料會顯示在位址列上,資料量小,最多為4kb。不安全 post:提交的資料不會在位址列上顯示。因此我們可以提交大量的資料,相對安全
轉發器
概念:一個web元件將未完成的任務交給另一個web元件繼續做,通常是一個servlet將資料獲取之後轉交給jsp進行展現.
下面講的是三種轉發中較為常用的一種轉發方式和步驟
轉發步驟:
1、繫結資料
request.setatteribute(string name,obj) name繫結名 obj:繫結值 伺服器端使用
2、獲取轉發器
requestdispatatcher rd = request.getrequestdispatcher(string url) url 要轉發到的路徑
3、啟動轉發
rd.forward(request,response)
注:轉發的本質是一個web元件通知容器呼叫另外一個web元件,(即呼叫service方法,所以需要傳遞request,response)
頁面獲取資料:
obj request.setAttribute(string name);//依據繫結名獲取繫結值,返回時時object型別的,需要強轉後使用
練習程式碼:
protected void service(HttpServletRequest req, HttpServletResponse resp){
//伺服器端
String str = "轉發器測試";
/** 繫結資料*/
req.setAttribute("key", emp);
/** 獲取轉發器*/
RequestDispatcher rd = req.getRequestDispatcher("emplist.jsp");
/**啟動轉發*/
rd.forward(req, resp);
}
/**========================================================================*/
//頁面
<% String str = (String) request.getAttribute("key"); %>
4、Servlet處理請求資源路徑
web.xm基礎l配置
<servlet>
<!--名稱(隨便起) -->
<servlet-name>count</servlet-name>
<!-- 要執行的servlet的路徑 -->
<servlet-class>com.hyxy.session.CountServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--也是名稱(要和上面的名稱一致) -->
<servlet-name>count</servlet-name>
<!-- 瀏覽器上要訪問的路徑名稱(絕對路徑下必須要有/ 後面的名稱可以隨便起) -->
<url-pattern>/count</url-pattern>
</servlet-mapping>
1、什麼是請求資源路徑 瀏覽器中的網址 http://ip:port/appName/url-pattern,請求資源路徑:appName/url-pattern2、處理原理 瀏覽器依據ip和port確定伺服器,之後依據appName確定應用程式所在的目錄,servlet容器預設瀏覽器請求的是一個Servlet元件, 所以會校驗web.xml裡的url-pattern,進行匹配,執行相關的Servlet元件。3、精確匹配 伺服器在進行web.xml裡的url-pattern的校驗時,會嚴格匹配請求路徑是否一致,如果匹配成功,就會執行相關資源 如: <url-pattern>/hello.html</url-pattern>嚴格匹配成功後,即使程式中有hello.html頁面,也不會返回這個頁面,而是執行相關Servlet。4、萬用字元匹配 萬用字元: * ,匹配0個或多個字元,必須使用斜槓 如:<url-pattern>/*</url-pattern> http://ip:port/appName/abc.html 匹配成功 http://ip:port/appName/service/add.html 匹配成功 http://ip:port/appName/listEmp 匹配成功 5、字尾匹配 在寫web.xml裡的url-pattern的值時,我們可以使用“ * . ”字尾的方式,字尾可以是1或多個字元組成的。 如:<url-pattern>*.action</url-pattern> http://ip:port/appName/abc.html 匹配失敗 http://ip:port/appName/emp/abc.action 匹配成功 http://ip:port/appName/listEmp.action 匹配成功 優先順序: 精確匹配最高 假如:web.xml中有三個Servlet元件,其url-pattern如下 <url-pattern>/abc.do</url-pattern> <url-pattern>/*</url-pattern> <url-pattern>*.do</url-pattern> 瀏覽器地址:http://ip:port/appName/abc.do 會執行精確匹配的Servlet元件如果精確匹配,萬用字元匹配,字尾匹配都沒有成功,容器會查詢是否有此檔案,如果有此檔案,打包資料返回給瀏覽器。如果沒有,返回404.
Servlet元件的合併
一般情況下,Servlet元件充當的角色為控制角色,控制角色的 作用是接收請求後進行分發到不同的資源裡。因此一個Servlet就可以 對請求資源路徑進行分析,使用分支結構來處理不同的資源。 如何合併: (1)採用字尾匹配進行修改web.xml (2)獲取請求資源路徑進行分析,然後使用if分支進行處理
5、重定向
1.概念:伺服器處理完業務邏輯後,向瀏覽器傳送一個狀態碼302,同時傳送一個訊息頭Location,此訊息頭的值是一個新地址。當瀏覽器接收這些資訊後,會立即向伺服器傳送該地址的請求 2、重定向的原理:可以參考:https://blog.csdn.net/kobejayandy/article/details/13745545 3、如何重定向 response.sendRedirect(String url) url:是重定向的新地址 4、重定向的特點 位址列的地址會發生改變。 重定向之前不能關閉流 兩次請求不共享request和response物件
6、異常錯誤處理
錯誤程式碼及其解決方法: 伺服器在處理完業務邏輯後,會響應瀏覽器,響應的內容包含了狀態編碼(數字型別) 200:表示成功處理業務。 404:伺服器處理的路徑存在問題,找不到相關請求資源 如: (1)在位址列上的路徑有問題(大小寫不對) (2)<url-pattern>的值與位址列路徑不一致 (3)兩個servlet-name不一致 (4)沒有部署專案 (5)專案的組織結構有問題 405:容器找不到Servlet元件的service方法 (1)方法名寫錯 (2)方法的引數型別有問題 (3)方法的異常,返回值有問題 500:容器找不到Servlet元件 (1)沒有繼承HttpServlet或實現Servlet介面 (2)<servlet-class>寫的不錯 (3)service裡的邏輯出現了問題
處理中文引數值
中文會出現亂碼,原因是編碼與解碼的字符集不一致造成 中文亂碼解決方式 方式1:服務端先編碼再解碼,適合 get/post req.setCharacterEncoding("utf-8") 伺服器端預設使用iso-8859-1解碼瀏覽器端常用的為utf-8進行編碼 方式2:只適合post request.setCharacterEncoding("utf-8") 位置:處理請求引數前 傳送響應時: response.setContentType("text/html;charset=utf-8") 位置:寫在獲取流之前
再寫程式碼時先將request.setCharacterEncoding("utf-8")和response.setContentType("http/html;charset=utf-8") 寫上這樣就能避免出現亂碼