Java Servlet 技術,簡稱Servlet,是Java中用於開發web應用程式的基本技術。 Servlet實際上也就是一個Java程式。一個Servlet應用程式通常包含很多Servlet。而我們熟知的JSP頁面最終也是要被編譯為Servlet。 Servlet應用程式是不能像一個普通類直接 ...
Java Servlet 技術,簡稱Servlet,是Java中用於開發web應用程式的基本技術。
Servlet實際上也就是一個Java程式。一個Servlet應用程式通常包含很多Servlet。而我們熟知的JSP頁面最終也是要被編譯為Servlet。
Servlet應用程式是不能像一個普通類直接運行的,它必須運行在Servlet容器中。
Servlet容器的作用就是將一個客戶端的請求傳給Servlet,並將Servlet應用程式的響應回傳給客戶端。
一. Servlet API 概述
Servlet API 中有4個Java包:
javax.servlet.*; javax.servlet.http.*; javax.servlet.annotation.*; javax.servlet.descriptor.*;
二. 關於第一個包 javax.servlet.* 的主要類型(沒有全部列出)
public interface javax.servlet.Servlet public interface javax.servlet.ServletRequest public interface javax.servlet.ServletResponse public interface javax.servlet.ServletContext public interface javax.servlet.ServletConfig public interface javax.servlet.RequestDispatcher public interface javax.servlet.Filter public abstract class GenericServlet extends java.lang.Object implements Servlet, ServletConfig, java.io.Serializable
三 . public interface javax.servlet.Servlet 介面
1.該介面中聲明的方法如下:
public void init(ServletConfig config) throws ServletException
public void service(ServletRequest req, ServletResponse res) throws ServletException,java.io.IOException
public ServletConfig getServletConfig()
public java.lang.String getServletInfo()
public void destroy()
2. Servlet技術的核心就是這個Servlet介面。這是所有Servlet類都必須直接或者間接實現的一個類。(直接實現就是一個Servlet類直接implements Servlet,間接實現
就是繼承一個實現了Servlet的類)。
Servelt介面定義了Servlet應用程式和Servlet之間的規則。這個規則就是:Servlet容器負責把Servlet類載入到記憶體中,併在Servlet實例中調用特定的方法(特別註
意:在一個Servlet應用程式中,每個Servlet只有一個實例。)。客戶端用戶的請求會觸發Servlet容器調用一個Servelt實例的service 方法,並傳遞給這個方法一個
ServletRequest實例和一個ServletResponse實例。ServletRequest實例封裝當前HTTP請求,它的作用是便於開發者解析和操作原始的HTTP數據;ServletResponse封裝當前
用戶的HTTP響應,它的作用是可以將響應回傳給客戶端。Servlet容器還為每個應用程式創建一個ServeltContext實例,其主要作用就是封裝了應用程式(Context)的環境細節。
每一個應用程式(Context)只有一個ServletContext實例。同時,Servlet容器還為每個應用程式創建一個ServeltConfig實例,它的主要作用就是封裝一些Servlet的配置信息。
關於ServletContext和ServletConfig後面會給出詳細的解說。
3. public void init(ServletConfig config) throws ServletException
第一次請求Servlet時,Servlet容器就會調用這個方法且只調用一次。
可在此方法中編寫一些於應用程式相關的初始化代碼。
Servlet容器會向該方法傳遞一個ServletConfig實例,一般會在init方法中將這個實例對象賦值給一個ServletCofig類型的成員變數。便於其他方法使用。
4. public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException
每次請求Servelt時都會調用這個方法。
在此方法中編寫實現程式功能和邏輯的代碼。
5. public void destroy()
卸載應用程式或者關閉應用程式時會調用destory()方法。
在此方法中編寫與資源清理相關的代碼。
6. public ServletConfig getServletConfig()
返回Servlet容器傳給init方法的ServletConfig。
為了讓這個方法不返回null,你需要將Servlet容器傳給init方法的ServletConfig對象賦值給一個類成員變數。
7. public java.lang.String getServletInfo()
返回任意有用的一個字元串或者null。
8.在演示實例之前必須知道我們在瀏覽器中輸入的url和我們編寫的servlet如何才能對應起來,換句話說就是在瀏覽器中輸入怎樣的url就可以調用相應的servlet
類。servlet中實現此功能有兩個技術:web.xml 和 @WebServlet註解。
①web.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <!-- <servlet-name>由你自己定,但是必須和 <servlet-mapping>中的<servlet-name>一致 --> <servlet-name> servletName </servlet-name> <!-- <servlet-class> 為你想要調用的servlet的全類名 --> <servlet-class> fullClassName </servlet-class>
<!-- 傳給servlet 的初始化參數,可以有多個 init-param 初始化參數這部分可以先忽略不看 直接看 <servlet-mapping> --> <init-param>
<!-- 參數名 --> <param-name> name </param-name>
<!-- 參數值 --> <param-value> value </param-value> </init-param> <init-param> <param-name>name</param-name> <param-value>admin</param-value> </init-param> </servlet>
<servlet-mapping> <servlet-name> servletName </servlet-name> <!-- 上面 <servlet-class> 類所匹配到瀏覽器輸入的url --> <url-pattern>/url</url-pattern> </servlet-mapping> </web-app>
② @WebServlet註解方式
/*
name 對應 web.xml的 <servlet-name>servletName</servlet-name>
urlPatterns 對應 web.xml的 <url-pattern>/url</servlet-name>
initParams={@WebInitParam(name="name",value="value")} 對應web.xml的 <init-param>
<param-name> name </param-name>
<param-value> value </param-value>
</init-param>
*/
@WebServlet(name="servletName",urlPatterns="/url", initParams={ @WebInitParam(name="name",value="value"), @WebInitParam(name="name1",value="value1") }) public class MyFirstServlet implements Servlet { // ....... }
③ 任意選擇上面的一種去配置。例如,採用註解方式配置如下:
@WebServlet(name="myFirstServlet",urlPatterns="/my", }) public class MyFirstServlet implements Servlet { //...... }
則瀏覽器輸入 http://localhost:8080/項目名稱/my 就可執行MyFirstServlet 這個servlet類,並調用init()方法和service()方法。
9. 關於前面知識的一個Servlet應用程式小實例。
package com.hjj.servlet.one; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebServlet; /* 採用@WebServlet註解的方式配置該servlet訪問路徑,此時就不需要在web.xml文件中進行配置 配置訪問路徑的屬性就是urlPatterns */ @WebServlet(name="MyFirstServlet",urlPatterns="/myFirstServlet") public class MyFirstServlet implements Servlet { private ServletConfig servletConfig = null; @Override public void destroy() { System.out.println("我是Detstroy方法,我被調用了 ^_^"); System.out.println("-----------------------servlet結束-------------------------"); } @Override public ServletConfig getServletConfig() { return this.servletConfig; } @Override public String getServletInfo() { return "myFirstServlet"; } @Override public void init(ServletConfig arg0) throws ServletException { System.out.println("----------------------servlet開始--------------------------"); this.servletConfig = arg0; // System.out.println("我是init方法,我被調用了 ^_^"); } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("我是service方法,我被調用了 ^_^"); String servletName = this.servletConfig.getServletName(); System.out.println("servletName = "+servletName); response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter(); pw.print("<html><head><head><title>我的第一個servlet app</title><body> hello "+servletName+"</body></html>"); System.out.println("---------------------------"); } }
① 在瀏覽器中首次輸入:http://localhost:8080/one/myFirstServlet
頁面顯示如下:
控制台:
②再次刷新頁面:html頁面依然不變
控制台:證明service方法會被調用多次,而init只被調用一次。
③此時在關閉伺服器,控制台輸出:可見destory方法在關閉容器後執行了
四. 關於init方法中傳遞的兩個參數ServletRequest和ServletResponse
1. ServletRequest
① 客戶端的每一次請求,Servlet容器都會創建一個ServletRequest實例,並將它傳遞給service方法。
Servlet封裝客戶端請求的相關信息。
② ServeltRequest介面的主要方法如下:
public int getContentType() //返回請求主體的MIME類型 public java.lang.String getParameter(java.lang.String name) //根據String類型的參數返回對應的值 public int getContentLength() //返回請求主體中的位元組數
我們平時最常用的就是上面紅色標註的方法。
例如使用如下url調用一個Servlet:
http://localhost:8080/myapp/myservelt?id=10
則在Servelt類中的service方法中使用ServletRequest就可以拿到這個值:ServletRequest.getParameter("id");
此外,如果傳遞給此方法的的字元不存在,該方法返回null。
2. ServletResponse
①ServletResponse介面表示一個Servlet響應。
在調用Servlet之前,Servlet容器都會創建一個ServletResponse並將其傳遞給service方法。
②ServletResponse介面常用方法
public java.io.PrintWriter getWriter() throws java.io.IOException //返回可以將文本傳給客戶端的java.io.PrintWriter實例 public void setContentType(java.lang.String type) //在給客戶端發送響應之前設置響應內容類型,例如 text/html,即發送的響應的類型為html。另外如果不進行設置,有些瀏覽器預設以html格式顯示,有些瀏覽器預設以文本格式顯示
該對象的應用在前面3.8的小實例中已經演示過,就不在演示了。
五. ServletContext
1. ServletContext表示Servlet應用程式。且每一個web應用程式只有一個ServletContext。
2. 同一個web應用的所有servlet對象共用一個ServletContext。Servlet對象可以通過它來訪問容器中的各種資源。
3. ServletContext 介面常用方法
public void setAttribute(java.lang.String name,java.lang.Object object) //把一個java對象和一個屬性名綁定,並存放到ServletContext中,參數name指定屬性名,參數Object表示共用數據。
public java.lang.Object getAttribute(java.lang.String name) //根據參數給定的屬性名,返回一個Object類型的對象。 和setAttribute方法是對應的
public java.util.Enumeration getAttributeNames() //返回一個Enumeration對象,該對象包含了所有存放在ServletContext中的屬性名。
public void removeAttribute(java.lang.String name) //根據參數指定的屬性名,從servletContext對象中刪除匹配的屬性。
public java.lang.String getServletContextName() //返回當前web應用的URL入口。
public java.lang.String getInitParameter(java.lang.String name) //返回web應用方位內的匹配的初始化參數值。在web.xml中<web-app>元素中<context-param>元素表示應用範圍內的初始化參數。其作用同下麵六中所講的的ServletConfig的getInitParameter()方法
public java.util.Enumeration getInitParameterNames() //返回一個Enumeration對象。
public java.lang.String getServletContextName() //返回web應用的名字。即<web-app>元素中<display-name>元素的值。
六. ServletConfig
1. Servlet封裝了@WebServlet 或者 web.xml 中Servlet的配置信息。
2. 這樣的信息叫做初始參數。初始參數由兩部分組成:鍵和值。
3. 那麼如何去獲取初始參數的值呢? ServletConfig提供了兩個方法:
public java.lang.String getInitParameter(java.lang.String name) //傳遞String類型的鍵,獲取鍵對應的值 public java.util.Enumeration getInitParameterNames() //返回所有初始參數名稱(也就是鍵)的一個Enmueration
4. ServletConfig還封裝了對ServletContext的操作。
public ServletContext getServletContext) //返回當前web應用的ServletContext實例
5. ServletConfig小實例演示。
package com.hjj.servlet.one; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; @WebServlet(name="testServiceConfig",urlPatterns="/testServiceConfig", initParams={ @WebInitParam(name="email",value="[email protected]"), @WebInitParam(name="name",value="test") }) public class TestServiceConfig implements Servlet { private ServletConfig servletConfig = null; @Override public void destroy() { } @Override public ServletConfig getServletConfig() { return this.servletConfig; } @Override public String getServletInfo() { return "myFirstServlet"; } @Override public void init(ServletConfig arg0) throws ServletException { this.servletConfig = arg0; } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("service被調用了"); String name = this.servletConfig.getInitParameter("name"); String email = this.servletConfig.getInitParameter("email"); System.out.println(); response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter(); pw.print("<html><head><head><title>testServletConfig</title><body>我的姓名 name:"+name+"<br>我的郵箱email:"+email+"</body></html>"); } }
瀏覽器輸入:http://localhost:8080/one/testServiceConfig
頁面顯示: