ServletContext介紹和基本使用方法
含義
當servlet容器(Tomcat)啟動時,會為每個Web應用建立一個唯一的ServletContext物件代表當前的web應用,不管在哪個servlet裡面,獲取到的這個類的物件都是同一個。
該物件不僅封裝了當前web應用的所有資訊,而且其作用範圍是整個專案,實現了多個Servlet之間的資料共享,但不能跨專案獲取。
伺服器啟動的時候,Tomcat會為託管的每一個web應用程式,建立一個ServletContext物件。當wen專案從伺服器中移除、或者伺服器關閉時,物件就會被銷燬。
主要作用:
- 獲取web應用程式的初始化引數
- 實現多個Servlet物件的資料共享;
- 讀取web應用下的資原始檔。
獲取
1、在HttpServlet中獲取
在init方法中,可以通過ServletConfig獲取
@Override
public void init(ServletConfig config) throws ServletException {
ServletContext servletContext = config.getServletContext();
}
還可以通過request獲取
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
}
在HttpServlet
的父類GenericServlet
中也已經實現了getServletConfig()
方法和getServletContext()
方法,可以直接在Servlet中呼叫。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
// 通過config物件獲取
ServletConfig servletConfig = this.getServletConfig();
ServletContext servletContext1 = servletConfig.getServletContext();
// 直接獲取
ServletContext servletContext2 = this.getServletContext();
}
實際上,GenericServlet
的原始碼中,getServletContext()
方法也是通過config物件實現的。
// GenericServlet部分原始碼
public ServletContext getServletContext() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getServletContext();
}
2、在TomcatListener中獲取
@Override
public void contextDestroyed(ServletContextEvent arg0) {
ServletContext servletContext = arg0.getServletContext();
}
3、在各種Config物件中獲取
上面已經介紹了HttpServlet
的init方法的ServletConfig
物件獲取,這裡再介紹一下通過Filter
的FilterConfig
物件獲取
@Override
public void init(FilterConfig config) throws ServletException {
ServletContext servletContext = config.getServletContext();
}
應用
獲取初始化引數
與web.xml的<web-app>
標籤中定義如下內容:
<context-param>
<param-name>name</param-name>
<param-value>張三</param-value>
</context-param>
與Servlet中定義如下內容:
package controller;
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("/ServletContextTest")
public class ServletContextTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取servletContext物件
ServletContext context = this.getServletContext();
//獲取引數對應的值
String name = context.getInitParameter("name");
System.out.println("Test01獲取name=" + name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
控制檯輸出結果(成功獲取):
實現資源共享
類似於request和session物件,ServletContext物件也是通過public void setAttribute(String name, Object object)
、public Object getAttribute(String name)
和public void removeAttribute(String name)
來實現資料資源共享並且操作資料的。且資料的作用域為整個web應用。
讀取資原始檔
參考了ServletContext的作用與應用(獲取網站登陸成功總人數)
config.properties檔案設定如下:
name=webapp.file.config.properties
存放位置:
Servlet程式碼(三種獲取方式):
// 使用context.getRealPath()
private void test01() throws FileNotFoundException, IOException {
//建立servletContext物件
ServletContext context = getServletContext();
//String path = context.getRealPath("");//獲取專案釋出到伺服器上的根路徑
String path = context.getRealPath("file\\config.properties");
System.out.println("Test01 path = " + path);
//建立properties物件
Properties properties = new Properties();
//建立輸入流物件
InputStream in = new FileInputStream(path);
//載入輸入流
properties.load(in);
//根據key獲取value值
String value = properties.getProperty("name");
System.out.println("Test01 name = " + value);
}
// 使用context.getResourceAsStream()
private void test02() throws FileNotFoundException, IOException {
ServletContext context = getServletContext();
InputStream in = context.getResourceAsStream("file/config.properties");
Properties pro = new Properties();
pro.load(in);
String name = pro.getProperty("name");
System.out.println("Test02 name = " + name);
}
// 使用this.getClass().getClassLoader().getResourceAsStream()
private void test03() throws FileNotFoundException, IOException {
Properties pro = new Properties();
InputStream in = this.getClass().getClassLoader().getResourceAsStream("../../file/config.properties");
pro.load(in);
String value = pro.getProperty("name");
System.out.println("Test03 name = " + value);
}
控制檯輸出結果:
Test01方法獲取了一個伺服器上資源的絕對路徑