天天看點

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

目錄

一、Servlet概述

二、Servlet執行過程

三、Servlet生命周期

四、Servlet的建立方式

4.1實作javax.serlvet.Servelt接口

4.2繼承javax.servlet.GenericServlet類

4.3繼承javax.servlet.http.HttpServlet類

五、Servlet映射

六、Servlet的線程安全

七、Servlet擷取配置資訊

7.1 ServletConfig

7.2 getInitParameter

八、ServletContext

8.1域對象

8.2擷取全局配置資訊

8.3擷取資源路徑

8.4實作請求轉發

九、Servlet相關對象

一、Servlet概述

servlet 是運作在Web伺服器中的小型 Java 程式(即:伺服器端的小應用程式),通常通過HTTP(超文本傳輸協定)接收和響應來自Web用戶端的請求。

編寫一個 servlet 程式主要有以下四步:

  1. 建立java類,實作servlet接口
  2. 修改web.xml檔案,給servlet提供一個可通路的URI位址
  3. 部署應用到tomcat伺服器
  4. 測試

下面我們寫一個小Demo,建立一個java類實作servlet接口,

import javax.servlet.*;
import java.io.IOException;

public class ServletDemo implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("servlet demo");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
           

接着配置web.xml檔案,提供可通路的URI位址,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletDemo</servlet-class>
    </servlet>

    <!--給servlet提供(映射)用戶端通路的URI-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
</web-app>
           

然後将項目配置到tomcat伺服器上,這裡我們将項目整個檔案夾複制到tomcat安裝目錄下的webapps中,

然後通過網址:http://localhost:8080/項目名稱/url-pattern名稱通路,得到控制台輸出結果:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

二、Servlet執行過程

上述例子的整個執行過程如下:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

Servlet通路類的順序如下:

  • 目前應用的類
  • lib下的所在類
  • tomcat/lib目錄的所有jar

三、Servlet生命周期

Servlet的生命周期分為四個階段:執行個體化、初始化、服務以及銷毀,以下是 Servlet 遵循的過程:

  • 構造 servlet,然後使用 init 方法将其初始化(執行個體化和初始化在servlet第一次被通路時調用)
  • 處理來自用戶端的對 service 方法的所有調用(服務在每次被通路時都會調用)
  • 從服務中取出 servlet,然後使用 destroy 方法銷毀它,最後進行垃圾回收并終止它(應用被解除安裝時會調用)

解除安裝應用可以使用tomcat官網的Manager App功能進行管理,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

在管理前首先要配置tomcat安裝路徑下conf檔案夾的tomcat-users.xml檔案,在檔案尾部添加使用者名和密碼,

<role rolename="manager-gui"/>
<user username="123" password="123" roles="manager-gui"/>
           

然後點選Manager App按鈕,輸入使用者名和密碼,就可以對伺服器上的應用進行管理了,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

除了生命周期方法之外,此接口還提供了 getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一種方法獲得任何啟動資訊,而後一種方法允許 servlet 傳回有關其自身的基本資訊,比如作者、版本和版權。

我們把生命周期的方法加入到servlet執行過程中,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

四、Servlet的建立方式

Servlet有三種建立方式,分别為:

  • 實作javax.serlvet.Servelt接口
  • 繼承javax.servlet.GenericServlet類(擴充卡模式)
  • 繼承javax.servlet.http.HttpServlet類(模闆方法設計模式)

4.1實作javax.serlvet.Servelt接口

主要是對Servlet接口的service方法進行重寫,詳細參見一中的Demo程式

4.2繼承javax.servlet.GenericServlet類

GenericServlet類實際上也實作了Servlet接口,我們如果直接實作Servlet接口,需要對五個方法都進行重寫,

而GenericServlet類對所有方法都重寫了,隻有service方法是抽象的,我們繼承GenericServlet類,隻需要對service方法進行重寫

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class ServletDemo2 extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("繼承GenericServlet");
    }
}
           

運作結果:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

4.3繼承javax.servlet.http.HttpServlet類

繼承HttpServlet類是開發中建立servlet的常用方法,屬于模闆方法設計模式,在實際開發任務中,該方法使用最多。

HttpServlet類是繼承了GenericServlet類,并實作了自己的一些特殊方法,根據用戶端請求方式的不同,使用不同的方法進行服務,

protected void doDelete(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理DELETE請求
protected void doGet(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理GET請求
protected void doHead(HttpServletRequest req, HttpServletResponse resp)//從protected service方法接收HTTP HEAD請求并處理該請求
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理Options請求
protected void doPost(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理POST請求
protected void doPut(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理PUT請求
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)//由伺服器(通過service方法)調用,以允許servlet處理TRACE請求
           

HttpServlet類對service方法進行了重載,

protected void service(HttpServletRequest req, HttpServletResponse resp)//接收來自public的service方法的标準HTTP請求,并将它們分派給在該類中定義的doXXX方法
void service(ServletRequest req, ServletResponse res)//将用戶端請求分派給protected的service方法
           

我們可以利用doXXX方法明确servlet的請求方式,

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
        System.out.println("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
        System.out.println("doPost");
    }
}
           

 運作結果:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

五、Servlet映射

我們可以配置多個映射路徑,通過不同的路徑通路同樣的内容,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletDemo3</servlet-class>
    </servlet>

    <!--給servlet提供(映射)用戶端通路的URI-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
    
    <!--設定不同的映射路徑-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo2</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo3</url-pattern>
    </servlet-mapping>
</web-app>
           

通過不同的url通路結果,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

還可以使用通配符*來代表任意字元串,

  • url-pattern:*abc,以abc結尾的任意字元串都可以通路
  • url-pattern:/abc,任意字元串都可以通路
  • url-pattern:/abc/*,以abc開頭的任意字元串都可以通路

在使用通配符進行url比對時,有如下的比對規則:

絕對路徑比對>/開頭比對>結尾比對

比如現在我們有四個servlet,對應着四個不同的映射關系,

Servlet1映射到/abc/*

Servlet2映射到/*

Servlet3映射到/abc

Servlet4映射到*.do

  • 當請求的url為"/abc/a.html"時,“/abc/*”和“/*”都比對,但是會優先比對“/abc/*”,即調用Servlet1
  • 當請求的url為"/abc"時,“/abc/*”和“/abc”都比對,但是會優先比對“/abc”,即調用Servlet3
  • 當請求的url為"/abc/a.do"時,“/abc/*”和“*.do”都比對,但是會優先比對“/abc/*”,即調用Servlet1
  • 當請求的url為"a.do"時,“/*”和“*.do”都比對,但是會優先比對“/*”,即調用Servlet2
  • 當請求的url為"/xxx/yyy/a.do"時,“/*”和“*.do”都比對,但是會優先比對“/*”,即調用Servlet2

如果url-pattern的值是/,表示執行預設映射。所有資源都是servlet

六、Servlet的線程安全

當用戶端第一次請求Servlet的時候,tomcat會根據web.xml配置檔案執行個體化servlet,

當又有一個用戶端通路該servlet的時候,不會再執行個體化該servlet,也就是多個線程在使用這個執行個體,即Servlet是單執行個體多線程通路的,

多線程下每個線程對局部變量都會有自己的一份copy,這樣對局部變量的修改隻會影響到自己的copy而不會對别的線程産生影響,線程安全的。

但是對于執行個體變量來說,由于servlet在Tomcat中是以單例模式存在的,所有的線程共享執行個體變量。多個線程對共享資源的通路就造成了線程不安全問題。

是以解決線程安全問題的最佳辦法就是,不寫全局變量,用局部變量

七、Servlet擷取配置資訊

這裡的配置資訊其實指的就是xml檔案中存儲的資料,我們有兩種方式。

7.1 ServletConfig

第一種方式擷取配置資訊用到的對象為ServletConfig,

我們建立一個servlet檔案,他會自動繼承HttpServlet類,并且包含兩個重寫的函數doPost()和doGet(),

擷取到配置檔案資訊需要用到ServletConfig對象,這個對象有兩種方法擷取,

void init(ServletConfig config);
ServletConfig getServletConfig();
           

我們重寫init()方法,将參數中的ServletConfig對象指派給我們自己寫的Servlet對象即可,

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletConfigDemo")
public class ServletConfigDemo extends HttpServlet {
    private ServletConfig config;

    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config=config;
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String str=config.getInitParameter("encoding");//擷取配置檔案資訊
        System.out.println(str);
    }
}
           

然後我們修改一下web.xml的映射路徑和執行個體對應關系,在servlet标簽中添加一個初始參數ini-param标簽,裡面建立一個encoding參數,值為GBK,然後使用ServletConfig對象擷取到encoding參數的值,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletConfigDemo</servlet-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
           

配置好了之後我們啟動Tomcat伺服器,因為這裡的映射路徑我們寫的是任意,這裡我們随意用通路url為:http://localhost:8080/test,回車看擷取的結果輸出,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

我們還可以通過繼承父類的方法獲得ServletConfig對象,然後調用getInitParameter()方法,

String str=this.getServletConfig().getInitParameter("encoding");
System.out.println(str);
           

7.2 getInitParameter

第二種方法是使用getInitParameter()的方法,該方法也是Servlet類定義的抽象方法,

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletConfigDemo2")
public class ServletConfigDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String str=super.getInitParameter("encoding");
        System.out.println(str);
    }
}
           

然後修改一下對應web.xml的綁定的路徑,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletConfigDemo2</servlet-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
           

下面是運作的結果:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

ServletConfig還有一個很重要的作用是擷取ServletText對象。

八、ServletContext

ServletContext代表的是整個應用,一個應用隻有一個ServletContext對象,為單執行個體。

該對象有三個主要作用:

  • 域對象
    • 在目前應用範圍内使用,使多個Servlet共享資料
  • 擷取全局配置資訊
  • 擷取資源路徑

8.1域對象

ServletContext作為目前應用範圍内的域對象,在目前應用範圍内使用,使多個Servlet共享資料,

共享資料是通過公共的map集合實作,以鍵值對的形式存儲資訊,主要有以下方法來操作map集合,

void setAttribute(String name,object value);//向ServletContext對象的map中添加資料
Object getAttribute(String name);//從ServletContext對象的map中取資料
void removeAttribute(String name);//根據name去移除資料
           

我們建立兩個Servlet,一個用來添加鍵值對,一個用來通路添加的鍵值對,

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo")
public class ServletContextDemo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext application=this.getServletContext();//通過調用getServletContext()方法擷取目前應用對象
        application.setAttribute("name","test");//向ServletContext的map中添加一個鍵值對
    }
}
           
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext application=this.getServletContext();
        String name=(String)application.getAttribute("name");//擷取map中指定鍵的值
        System.out.println(name);//輸出擷取到的值
    }
}
           

然後設定web.xml中的映射路徑,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletContextDemo</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>servletDemo2</servlet-name>
        <servlet-class>ServletContextDemo2</servlet-class>
    </servlet>

    <!--給servlet提供(映射)用戶端通路的URI-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>servletDemo2</servlet-name>
        <url-pattern>/demo2</url-pattern>
    </servlet-mapping>
</web-app>
           

我們首先通過http://localhost:8080/demo通路ServletContextDemo類建立鍵值對,然後通路http://localhost:8080/demo2擷取值資訊,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

8.2擷取全局配置資訊

ServletConfig對象的getInitParameter()方法可以擷取定義在<servlet>标簽中的參數,

而ServletContext作為目前應用的全局對象,它的getInitParameter()方法可以擷取定義在<servlet>标簽外的參數,

我們首先在web.xml中定義一個全局配置資訊<context-param>,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <context-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </context-param>
    
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletContextDemo3</servlet-class>
    </servlet>

    <!--給servlet提供(映射)用戶端通路的URI-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
</web-app>
           

然後建立一個servlet類,用于通路該全局配置資訊并輸出,

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();//擷取全局應用對象
        String encoding=servletContext.getInitParameter("encoding");//擷取全局配置資訊
        System.out.println(encoding);//輸出配置資訊
    }
}
           

并把類名更新到web.xml的servlet執行個體中,下面是顯示的結果,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

8.3擷取資源路徑

ServletContext還可以用來擷取資源的路徑,使用的方法為,

String getRealPath(String path);//根據資源名稱得到資源的絕對路徑
           

該方法可以得到目前應用任何位置的任何資源,我們首先在項目中建立幾個資源檔案,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

然後我們通過getRealPath()方法擷取絕對路徑,并用Properties類擷取配置檔案的資訊,

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

@WebServlet(name = "ServletContextDemo4")
public class ServletContextDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();//擷取全局應用對象
        String path=servletContext.getRealPath("/WEB-INF/a.properties");//參數要以/開頭,代表目前應用的根目錄\

        //建立Properties,讀取配置檔案中的資訊
        Properties pro=new Properties();
        pro.load(new FileInputStream(path));
        System.out.println(pro.getProperty("key"));//擷取key鍵對應的值
    }
}
           

輸出結果如下:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

 把路徑換為其他的可以通路别的配置檔案,需要注意src中的所有檔案輸出後都在WEB-INF的classes檔案中,

String path=servletContext.getRealPath("/WEB-INF/classes/b.properties");//通路b.properties
String path=servletContext.getRealPath("/WEB-INF/classes/test/c.properties");//通路c.properties
           

8.4實作請求轉發

實作請求轉發就是浏覽器發送請求給servlet1,servlet1将請求轉發給servlet2,讓servlet2完成請求之後,然後将結果傳回給servlet1,最後傳回給浏覽器,

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

使用的方法為,

RequestDispatcher getRequestDispatcher(String path);//參數表示請求跳轉的目的地
           

我們建立兩個servlet,讓ServletContextDemo5把請求轉發給ServletContextDemo6來處理,

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo5")
public class ServletContextDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext application=this.getServletContext();//擷取全局應用對象
        RequestDispatcher rd=application.getRequestDispatcher("/demo6");
        rd.forward(request,response);//将請求向下傳遞
    }
}
           
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "ServletContextDemo6")
public class ServletContextDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到轉發的請求,處理完成");
    }
}
           

然後我們配置web.xml資訊,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--建立一個servlet執行個體-->
    <servlet>
        <servlet-name>servletDemo</servlet-name>
        <servlet-class>ServletContextDemo5</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>servletDemo6</servlet-name>
        <servlet-class>ServletContextDemo6</servlet-class>
    </servlet>

    <!--給servlet提供(映射)用戶端通路的URI-->
    <servlet-mapping>
        <servlet-name>servletDemo</servlet-name>
        <url-pattern>/demo</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>servletDemo6</servlet-name>
        <url-pattern>/demo6</url-pattern>
    </servlet-mapping>
</web-app>
           

接着我們啟動伺服器,通路url:http://localhost:8080/demo,可以看到已經将請求傳遞給了servlet6,結果如下:

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

九、Servlet相關對象

JavaWeb——(8)Servlet一、Servlet概述二、Servlet執行過程三、Servlet生命周期四、Servlet的建立方式五、Servlet映射六、Servlet的線程安全七、Servlet擷取配置資訊八、ServletContext九、Servlet相關對象

繼續閱讀