Servlet中ServletConfig和ServletContext漫談

Servlet的API有不少,這裏只談談兩個Servlet對象:ServletConfig對象和ServletContext對象。java

1. ServletConfig對象

        在Servlet的配置文件中,可使用一個或多個<init-param>標籤爲servlet配置一些初始化參數,當Servlet配置了初始化參數後,web容器在建立servlet實例對象時,會自動將這些參數封裝到ServletConfig對象中,並在調用Servlet的init方法時,將ServletConfig對象傳遞給Servlet。進而,程序員經過ServletConfig對象就能夠獲得當前Servlet的初始化參數信息。該對象的getInitParameter(String name)用來得到指定參數名的參數值,getInitParameterNames()用來得到全部參數名,咱們測試一下:程序員

        在test工程的src下新建一個包servletConfig,而後新建一個ServletConfigDemo1類,在配置文件裏進行以下配置:web

<servlet>  
    <servlet-name>ServletConfigDemo1</servlet-name>  
    <servlet-class>servletConfig.ServletConfigDemo1</servlet-class>  
    <init-param>  
    <param-name>category</param-name>  
    <param-value>book</param-value>  
    </init-param>       
    <init-param>  
    <param-name>school</param-name>  
    <param-value>tongji</param-value>  
    </init-param>       
    <init-param>  
    <param-name>name</param-name>  
    <param-value>java</param-value>  
    </init-param>       
</servlet>  
<servlet-mapping>  
    <servlet-name>ServletConfigDemo1</servlet-name>  
    <url-pattern>/ServletConfigDemo1</url-pattern>  
</servlet-mapping> 

        在ServletConfigDemo1.java中的代碼以下:數據庫

public class ServletConfigDemo1 extends HttpServlet {  
    ServletConfig config = null;      
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        String value = config.getInitParameter("category");//獲取指定的初始化參數  
        resp.getOutputStream().write((value + "<br/>").getBytes());  
          
        Enumeration e = config.getInitParameterNames();//獲取全部參數名  
        while(e.hasMoreElements()){  
            String name = (String) e.nextElement();  
            value = config.getInitParameter(name);  
            resp.getOutputStream().write((name + "=" + value + "<br/>").getBytes());  
        }  
    }  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }  
    @Override  
    public void init(ServletConfig config) throws ServletException {          
        this.config = config; //初始化時會將ServletConfig對象傳進來  
    }  
}  

        在瀏覽器中輸入:http://localhost:8080/test/ServletConfigDemo1,便可在瀏覽器中顯示讀取參數的結果。瀏覽器

        注:實際開發中,並不須要重寫init方法,以上代碼中重寫init方法是爲了說明config對象的傳遞過程。其實在父類的init方法中已經實現了該config的傳遞了,咱們只要直接調用getServletConfig()就能夠獲得config對象,即在doGet方法中直接經過下面的調用方式得到ServletConfig對象:bash

  1. ServletConfig config = this.getServletConfig();  

        那麼ServletConfig對象有什麼做用呢?通常主要用於如下狀況:app

         1)得到字符集編碼;ide

         2)得到數據庫鏈接信息;測試

         3)得到配置文件,查看struts案例的web.xml文件等。this

2. ServletContext對象

        web容器在啓動時,它會爲每一個web應用程序都建立一個對應的ServletContext對象,它表明當前web應用(web工程)。在ServletConfig接口中有個getServletContext方法用來得到ServletContext對象;ServletContext對象中維護了ServletContext對象的引用,也能夠直接得到ServletContext對象。因此開發人員在編寫Servlet時,能夠經過下面兩種方式得到ServletContext對象:

  1. this.getServletConfig().getServletContext();  
  2. this.getServletContext();  

        通常直接得到便可。
        因爲一個web應用中的全部Servlet共享同一個ServletContext對象,所以Servlet對象之間能夠經過ServletContext對象來實現通信,ServletContext對象一般也被稱爲context域對象。有以下主要方法:

getResource(String path); //方法得到工程裏的某個資源  
getResourceAsStream(String path); //經過路徑得到跟資源相關聯的流  
setAttribute(Sring name, Object obj); //方法往ServletContext裏存對象,經過MAP集合來保存。  
getAttribute(String name); //方法從MAP中取對象  
getInitParameter(String name); //得到整個web應用的初始化參數,  
//這個跟ServletConfig獲取參數不一樣,這是在<context-param></context-param>中定義的,config對象裏的getInitParameter方法得到的是具體某個servlet的初始化參數。  
getNamedeDispatcher(String name); //方法用於將請求轉給另外一個servlet處理,參數表示要轉向的servlet。  
//調用該方法後,要緊接着調用forward(ServletRequest request, ServletResponse response)方法  
getServletContextName(); // 得到web應用的名稱。

        ServletContext應用有哪些呢?
         1)多個Servlet經過ServletContext對象實現數據共享(見下面的Demo1和Demo2)
         2)獲取web應用的初始化參數(見Demo3)
         3)實現Servlet的轉發(見Demo4和Demo5)
         4)利用ServletContext對象讀取資源文件(xml或者properties)(見Demo6)

        下面對ServletContext對象寫幾個Demo測試一下:

Demo1:往context域中存入數據

public class ServletContextDemo1 extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {        
        String data = "adddfdf";  
        ServletContext context = this.getServletConfig().getServletContext();  
        context.setAttribute("data", data);//將數據寫到ServletContext  
    }  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }     
}  

Demo2:從context域中讀取數據

public class ServletContextDemo2 extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {        
        ServletContext context = this.getServletContext();  
        String data = (String) context.getAttribute("data");//經過鍵值從ServletContext中獲取剛纔存入的數據  
        resp.getOutputStream().write(data.getBytes());  
    }  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
          
        doGet(req, resp);         
    }     
} 

Demo3:獲取整個web應用的初始化參數

public class ServletContextDemo3 extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
  
        ServletContext context = this.getServletContext();  
        String url = context.getInitParameter("url");//獲取整個web應用的初始化參數,參數是在<context-param></context-param>中定義的  
        resp.getOutputStream().write(url.getBytes());  
    }  
  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
  
        doGet(req, resp);         
    }         
}

 

Demo4:實現轉發

public class ServletContextDemo5 extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        ServletContext context = this.getServletContext();  
        RequestDispatcher rd = context.getRequestDispatcher("/ServletContextDemo5");  
        rd.forward(req, resp);//將請求轉發給ServletContextDemo5.java處理  
    }  
  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }     
}  

Demo5:

public class ServletContextDemo5 extends HttpServlet {  
  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        resp.getOutputStream().write("ServletDemo5".getBytes());//處理ServletDemo4傳過來的請求  
    }  
  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }  
      
} 

Demo6:讀取資源文件

public class ServletContextDemo6 extends HttpServlet {  
  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        //test1(resp);  
        //test2(resp);  
        //test3(resp);  
        //test4();  
    }  
      
    //讀取文件,並將文件拷貝到e:\根目錄,若是文件太大,只能用servletContext,不能用類裝載器  
    private void test4() throws FileNotFoundException, IOException {  
        String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");  
        String filename = path.substring(path.lastIndexOf("\\")+1);  
          
        InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");  
        byte buffer[] = new byte[1024];  
        int len = 0;  
          
        FileOutputStream out = new FileOutputStream("e:\\" + filename);  
        while((len = in.read(buffer)) > 0){  
            out.write(buffer, 0, len);  
        }  
    }  
  
    //使用類裝載器讀取源文件(不適合裝載大文件)  
    private void test3(HttpServletResponse resp) throws IOException {  
        ClassLoader loader = ServletContextDemo6.class.getClassLoader();  
        InputStream in = loader.getResourceAsStream("db.properties");  
        Properties prop = new Properties();  
        prop.load(in);  
        String driver = prop.getProperty("driver");  
        resp.getOutputStream().write(driver.getBytes());  
    }  
  
    private void test2(HttpServletResponse resp) throws FileNotFoundException,  
                    IOException {  
        String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");//獲取絕對路徑  
        FileInputStream in = new FileInputStream(path);//傳統方法,參數爲絕對路徑  
          
        Properties prop = new Properties();  
        prop.load(in);  
        String driver = prop.getProperty("driver");  
        resp.getOutputStream().write(driver.getBytes());  
    }  
  
    //讀取web工程中資源文件的模板代碼(源文件在工程的src目錄下)  
    private void test1(HttpServletResponse resp) throws IOException {  
        InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");  
        ////注:源文件若在工程的WebRoot目錄下,則上面參數路徑直接爲"/db.properties",由於WebRoot即表明web應用  
        Properties prop = new Properties();  
        prop.load(in);//先裝載流  
        String driver = prop.getProperty("driver");  
        String url = prop.getProperty("url");  
        String username = prop.getProperty("username");  
        String password = prop.getProperty("password");  
        resp.getOutputStream().write(driver.getBytes());  
    }  
  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }     
}
相關文章
相關標籤/搜索