天天看點

第一章_servlet

javax.servlet 包含定義servlet與servlet容器之間契約的類和接口

javax.servlet.http 包含定義http servlet與servlet容器之間契約的類和接口

javax.servlet.annotation 包含對servlet、filter和listener進行标注的注解。它還為标注元件指定中繼資料。

javax.servlet.descriptor 包含為web應用程式的配置資訊提供程式設計式通路的類型。

servlet技術的核心是servlet接口,這是所有servlet類都必須直接或者間接實作的一個接口。使用者的請求會引發servlet容器調用一個servlet的service方法,并給這個方法傳入一個servletrequest執行個體和一個servletresponse執行個體。

servlet接口定義了以下5個方法。

void init(servletconfig config) throws servletexception

void destroy()

java.lang.string getservletinfo()

servletconfig getservletconfig()

init、service和destroy方法屬于servlet聲明周期方法。servlet容器将根據以下原則調用這三個方法。

1. init。第一次請求servlet時,servlet容器就會調用這個方法。在後續的請求中,将不再調用該方法。可以利用這個方法來編寫一些應用程式初始化相關的代碼。在調用這個方法時,servlet容器會傳遞一個servletconfig。一般來說,會将servletconfig賦給一個類級變量,以便servlet類中的其他方法也可以使用這個對象。

2. service。每次請求servlet時,servlet容器都會調用這個方法。必須在這裡編寫要servlet完成的相應代碼,第一次請求servlet時,servlet容器會調用init方法和service方法,對于後續請求,則隻調用service方法。

3. destroy。要銷毀servlet時,servlet容器就會調用這個方法。它通常發生在解除安裝應用程式,或者關閉servlet容器的時候。一般來說,可以在這個方法中編寫一些資源清理相關的代碼。

servlet中的另外兩個方法是非聲明周期方法:getservletinfo和getservletconfig。

1.  getservletinfo。該方法傳回servlet的描述,可以傳回可能有用的任意字元串,甚至是null。

2. getservletconfig。該方法傳回由servlet容器傳給init方法的servletconfig。但是,為了讓getservletconfig傳回非null值,你肯定已經為傳給init方法的servletconfig賦給了一個類級變量。

*必須注意個一點是線程安全性。一個應用程式中的所有使用者将共用一個servlet執行個體,是以不建議使用類級變量,除非他們是隻讀的,或者是java.util.concurrent.atomic包中的成員。

1.3、編寫基礎的servlet應用程式

package servlet;  

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(name="myservlet",urlpatterns={"/my"})  

public class myservlet implements servlet{  

    private transient servletconfig servletconfig ;  

    @override  

    public void destroy() {  

        // todo auto-generated method stub  

    }  

    public servletconfig getservletconfig() {  

        return servletconfig;  

    public string getservletinfo() {  

        return "my servlet";  

    public void init(servletconfig servletconfig) throws servletexception {  

        this.servletconfig = servletconfig ;  

    public void service(servletrequest req, servletresponse res)  

            throws servletexception, ioexception {  

        string servletname = servletconfig.getservletname() ;  

        res.setcontenttype("text/html");  

        printwriter writer = res.getwriter() ;  

        writer.print("<html><head></head><body>hello from " + servletname + "</body></html>") ;  

}  

第一章_servlet

對于每一個http請求,servlet容器都會建立一個serveltrequest執行個體,并将它傳給servlet的service方法。servletrequest封裝有關請求的資訊。

下面是servletrequest接口中的方法。

public int getcontentlength()

傳回請求主體中的位元組數。如果不知道位元組的長度,該方法将傳回-1。

public java.lang.string getcontenttype()

傳回請求主體mime類型,如果不知道類型,則傳回null。

public java.lang.string getparameter(java.lang.string name)

傳回指定請求參數的值

public java.lang.string getprotocol()

傳回這個http請求的協定名稱和版本号

getparameter是servletrequest中最常用的方法。該方法通常用來傳回一個html表單域的值。

getparameter也可以用來擷取查詢字元串的值。例如:如果利用下面這個uri調用一個servlet:

<a target="_blank" href="http://domain/context/servletname?id=123">http://domain/context/servletname?id=123</a>

将可以在servlet中利用下面這個語句來擷取id的值

string id = request.getparameter(“id”) ;

注意,如果該參數不存在,那麼getparameter将傳回null。

servletresponse中定義的其中一個方法是getwriter方法,它傳回可以将文本傳給用戶端的java.io.printwriter。在預設情況下,printwriter對象采用iso-8859-1編碼。

為了從一個servlet内部擷取某個初始參數的值,應該在由servlet容器傳給servlet的init方法的servletconfig中調用getinitparameter方法。getinitparameter方法的簽名如下:

java.lang.getinitparameter(java.lang.string name) ;

此外,getinitparameternames方法則是傳回所有初始化參數名稱的一個enumeration:

java.util.enumeration&lt;java.lang.string&gt; getinitparameternames()

除了這2個方法外,servletconfig還提供了另一個很有用的方法:getservletcontext。可以利用這個方法從servlet内部擷取servletcontext。

import javax.servlet.annotation.webinitparam;  

@webservlet(name="servletconfigdemoservlet",  

        urlpatterns={"/servletconfigdemo"},  

        initparams={  

            @webinitparam(name="admin",value="benjamin"),  

            @webinitparam(name="email",value="[email protected]")  

        }  

    )  

public class servletconfigdemoservlet implements servlet{  

        return "servletconfig demo";  

        servletconfig servletconfig = getservletconfig() ;  

        string admin = servletconfig.getinitparameter("admin") ;  

        string email = servletconfig.getinitparameter("email") ;  

        writer.print("&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;admin:"+admin+"&lt;br/&gt;email:"+email+"&lt;/body&gt;&lt;/html&gt;") ;  

第一章_servlet

servletcontext辨別servlet應用程式。每個web應用程式隻有一個context。在分布式環境中,一個應用程式同時部署到多個容器中,并且每台java虛拟機都有一個servletconfig對象。

在servletconfig中調用getservletcontext方法可以獲得servletcontext。

genericservlet通過在init方法中将servletconfig對象賦給一個類級變量servlet-config,實作對servletconfig的儲存。下面是geneericservlet的源代碼:

package javax.servlet;  

import java.io.serializable;  

import java.util.enumeration;  

import java.util.resourcebundle;  

public abstract class genericservlet  

  implements servlet, servletconfig, serializable  

{  

  private static final string lstring_file = "javax.servlet.localstrings";  

  private static resourcebundle lstrings = resourcebundle.getbundle("javax.servlet.localstrings");  

  private transient servletconfig config;  

  public void destroy()  

  {  

  }  

  public string getinitparameter(string name)  

    servletconfig sc = getservletconfig();  

    if (sc == null) {  

      throw new illegalstateexception(lstrings.getstring("err.servlet_config_not_initialized"));  

    return sc.getinitparameter(name);  

  public enumeration&lt;string&gt; getinitparameternames()  

    return sc.getinitparameternames();  

  public servletconfig getservletconfig()  

    return this.config;  

  public servletcontext getservletcontext()  

    return sc.getservletcontext();  

  public string getservletinfo()  

    return "";  

  public void init(servletconfig config)  

    throws servletexception  

    this.config = config;  

    init();  

  public void init()  

  public void log(string msg)  

    getservletcontext().log(getservletname() + ": " + msg);  

  public void log(string message, throwable t)  

    getservletcontext().log(getservletname() + ": " + message, t);  

  public abstract void service(servletrequest paramservletrequest, servletresponse paramservletresponse)  

    throws servletexception, ioexception;  

  public string getservletname()  

    return sc.getservletname();  

大家考慮一下為什麼genericservlet中有兩個init方法?

genericservlet通過在init方法中将servletconfig對象賦給一個類級變量servletconfig,實作對servletconfig的儲存。

但是如果在類中覆寫了這個方法,則調用servlet中的init方法,并且必須調用super.init(servletconfig)來儲存servletconfig。為了避免這麼做,genericservlet又另外提供了一個init方法,它不帶參數。當把servletconfig賦給servletconfig之後,這個方法就會被第一個init方法調用,進而不影響servletconfig的建立。

1.9.1 httpservlet

httpservlet類覆寫javax.servlet.genericservlet類,在使用httpservlet時,還要使用httpservletrequest和httpservletresponse對象,它們分别辨別servlet請求和servlet響應。httpservletrequest接口內建javax.servlet.servletrequest,httpservletresponse繼承javax.servlet.servletresponse。

這個新的service方法與javax.servlet.servlet中的差別在于,前者接受的是httpservletrequest和httpservletresponse,而不是servletrequest和servletresponse。

原始的service方法将請求和響應對象進行向下轉換,分别從servlet容器轉換成httpservletrequest和httpservletresponse,并調用新的service方法。

httpservlet中新的service方法會檢視通常用來發送琴秋(通過調用request.getmethod)的http方法,并調用以下某個方法(doget、dopost、dohead、doput、dotrace、dooptions和dodelete)。

總之,httpservlet中有兩項特性是genericservlet所沒有的:

1、不覆寫service方法,而是覆寫doget、dopost,或者兩者都覆寫調。

2、将用httpservletrequest和httpservletresponse代替servletrequest和servletresponse

1.9.2 httpservletrequest

httpservletrequest表示http環境中的servlet請求。它內建javax.servlet.servletrequest接口,并增加了幾個方法,例如:

java.lang.string getcontextpath()

傳回表示請求context的請求uri部分。

cookie[] getcookies()

傳回一個cookie對象數組

java.lang.string getheader(java.lang.string name)

傳回指定http标頭的值

java.lang.string getmethod()

傳回發出這條請求的http方法的名稱

java.lang.string getquerystring()

傳回請求url中的查詢字元串

httpsession getsession()

傳回與這個請求有關的session對象。如果沒有找到,則建立新的session對象。

httpsession getsession(boolean create)

傳回與這個請求有關的session對象。如果沒有找到,并且create參數為true,那麼将建立新的session對象。如果為false,傳回空

1.9.3 httpservletresponse

httpservletresponse表示http環境下的servlet響應。下面是其中定義的部分方法:

void addcookie(cookie cookie)

給這個響應對象添加cookie

void addheader(java.lang.string name,java.lang.string value)

給這個響應對象添加标頭

void sendredirect(java.lang.string location)

發送響應代号,将浏覽器重定向到指定的位置

package app01c;  

import javax.servlet.http.httpservlet;  

import javax.servlet.http.httpservletrequest;  

import javax.servlet.http.httpservletresponse;  

@suppresswarnings("serial")  

public class simpleservlet extends httpservlet{  

    protected void doget(httpservletrequest req, httpservletresponse resp)  

        resp.setcontenttype("text/html") ;  

        printwriter writer = resp.getwriter() ;  

        writer.print("&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;simple servlet&lt;/body&gt;&lt;/html&gt;") ;  

public class welcomeservlet extends httpservlet{  

        writer.print("&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;welcome&lt;/body&gt;&lt;/html&gt;") ;  

&lt;?xml version="1.0" encoding="utf-8"?&gt;  

&lt;web-app version="2.5"   

    xmlns="http://java.sun.com/xml/ns/javaee"   

    xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"   

    xsi:schemalocation="http://java.sun.com/xml/ns/javaee   

    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&gt;  

  &lt;welcome-file-list&gt;  

    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;  

  &lt;/welcome-file-list&gt;  

  &lt;servlet&gt;  

    &lt;servlet-name&gt;ss&lt;/servlet-name&gt;  

    &lt;servlet-class&gt;app01c.simpleservlet&lt;/servlet-class&gt;  

    &lt;load-on-startup&gt;10&lt;/load-on-startup&gt;  

  &lt;/servlet&gt;  

  &lt;servlet-mapping&gt;  

    &lt;url-pattern&gt;/simple&lt;/url-pattern&gt;  

  &lt;/servlet-mapping&gt;  

   &lt;servlet&gt;  

    &lt;servlet-name&gt;ww&lt;/servlet-name&gt;  

    &lt;servlet-class&gt;app01c.welcomeservlet&lt;/servlet-class&gt;  

    &lt;load-on-startup&gt;20&lt;/load-on-startup&gt;  

    &lt;url-pattern&gt;/welcome&lt;/url-pattern&gt;  

&lt;/web-app&gt;  

這樣我們就可以利用下面這些路徑去通路它們了:

http://localhost:8080/app01c/simple

http://localhost:8080/app01c/welcome

servlet技術是javaee技術的組成部分。servlet容器中運作的所有servlet,以及容器與servlet之間的契約,都采用了javax.servlet.servlet接口的形式。javax.servlet包也提供了實作servlet接口的genericservlet抽象類。這是一個便利類,可以通過擴充它來建立servlet。但是,大多數現代的servlet都在http環境中處理請求。是以,将javax.servlet.http.httpservlet類子類化會更有意義。httpservlet類本身也是genericservlet的一個子類。