07-javax.servlet.ServletContext
阿新 • • 發佈:2021-08-06
接著上面筆記中的ServletConfig介面中最後一個方法,
我們新建一個web專案c-ServletContext,
該專案中的兩個Servlet實現類為AServlet和BServlet,
將init中的區域性變數ServletConfig物件賦值給一個私有的成員變數config,
在各自的service方法中用該物件呼叫ServletConfig介面中的獲取Servlet物件上下文的方法getServletContext分別在兩個實現類中獲取,並輸出到瀏覽器。其他配置就不贅述了。
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-name>servletcontext1</servlet-name> <servlet-class>com.servlet.AServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletcontext1</servlet-name> <url-pattern>/a</url-pattern> </servlet-mapping> <servlet> <servlet-name>servletcontext2</servlet-name> <servlet-class>com.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletcontext2</servlet-name> <url-pattern>/b</url-pattern> </servlet-mapping> </web-app>
兩個實現類中方法的程式碼如下
private ServletConfig config = null; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; } @Override public ServletConfig getServletConfig() { return config; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { ServletConfig config = getServletConfig(); ServletContext application = config.getServletContext(); System.out.println(application); } @Override public String getServletInfo() { return null; } @Override public void destroy() { }
部署執行,在瀏覽器輸入URL轉到index頁面,點選其中的兩個連線分別輸出兩個Servlet物件中獲取的ServletContext物件,可以看到執行視窗輸出如下
兩個Servlet物件輸出的兩個ServletContext物件記憶體地址相同,是同一個物件。並且該介面由Tomcat伺服器實現,儲存的地址是org.apache.catalina.core包下,實現類的類名是ApplicationContextFacade.java
結論:
--javax.servlet.ServetContext介面: 1、Tomcat伺服器完成對這個介面的實現 完整的類名為:org.apache.catalina.core.ApplicationContextFacade javaweb程式設計師無需關心這個實現類,只需要面向ServetContext介面呼叫介面中的方法就行了。 2、ServletContext具體是什麼?什麼時候被建立?什麼時候被銷燬?建立幾個? --ServletContext翻譯為:Servlet上下文 --一個webapp只有一個web.xml檔案,該檔案在伺服器啟動時被解析 --一個webapp只有一個ServletContext物件,該物件也是在伺服器啟動階段被例項化 --ServletContext物件在伺服器關閉時被銷燬 --ServletContext物件對應的是web.xml檔案,也可以說這個物件在專案執行時是web.xml檔案的代表 --ServletContext物件是所有Servlet物件周圍環境的代表 【在同一個webapp中所有Servlet物件共享一個環境,也就是共享同一個ServletContext物件】 --當所有使用者希望共享一個數據,可以將該資料存放到ServletContext物件中, 但是放進ServletContext物件中的資料不建議涉及修改操作,因為該物件是多執行緒共享的,修改會有執行緒安全問題。 3、ServletContext介面中常用的重點方法 --Object getAttribute(String name) 獲取ServletContext範圍中的資料,在底層該方法是呼叫了集合的get方法,Object value=map.get(key.value) --void removeAttribute(String name) 移除ServletContext範圍中的資料,在底層該方法是呼叫了集合的remove方法,map.remove(key) --void setAttribute(String name, Object object) 向ServletContext範圍中新增資料,在底層該方法是呼叫了集合的put方法,map.put(key,value) 下面兩個方法和ServletConfig介面中的一樣,只不過獲取web.xml檔案中的資訊是在<servlet></servlet>標籤之外定義的上下文初始化引數標籤<context-param>標籤中的內容,具體xml檔案程式碼如下面所示。 --String getInitParameter(String name) --Enumeration getInitParameterNames() --String getRealPath(String path) 該方法是獲取檔案的絕對路徑,演示如下 4、Servlet、ServletConfig和ServletContext之間的關係 --一個Servlet物件對應一個ServletConfig物件 --一個webapp中的所有Servlet物件共享一個ServletContext物件 5、從測試將資料儲存到ServletContext範圍以及從中讀取的操作中 我們知道ServletContext範圍可以跨使用者傳遞,不同使用者點選連線照樣可以獲取資料可以儲存資料。
1、測試String getInitParameter(String name)和Enumeration getInitParameterNames()方法,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">
<!--web.xml檔案中配置上下文引數,該資訊在伺服器啟動階段解析xml檔案時自動封裝到ServletContext物件中-->
<context-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>123</param-value>
</context-param>
<servlet>
<servlet-name>servletcontext1</servlet-name>
<servlet-class>com.servlet.AServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletcontext1</servlet-name>
<url-pattern>/a</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>servletcontext2</servlet-name>
<servlet-class>com.servlet.BServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletcontext2</servlet-name>
<url-pattern>/b</url-pattern>
</servlet-mapping>
</web-app>
service方法中的程式碼
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
ServletConfig config = getServletConfig();
ServletContext application = config.getServletContext();
//System.out.println(application);
//ServletContext介面中獲取所有上下文初始化引數的name的方法
Enumeration<String> names = application.getAttributeNames();
//遍歷集合,並獲取上下文初始化引數name對應的value
while (names.hasMoreElements()){
String name = names.nextElement();
String value = application.getInitParameter(name);
System.out.println(name+" = "+value);
}
}
結果如下
測試String getRealPath(String path)方法,獲取檔案絕對路徑
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
ServletConfig config = getServletConfig();
ServletContext application = config.getServletContext();
//System.out.println(application);
//ServletContext介面中獲取所有上下文初始化引數的name的方法
Enumeration<String> names = application.getInitParameterNames();
//遍歷集合,並獲取上下文初始化引數name對應的value
while (names.hasMoreElements()){
String name = names.nextElement();
String value = application.getInitParameter(name);
System.out.println(name+" = "+value);
}
//獲取檔案絕對路徑方法
//下面這樣寫必須webapp根路徑(即WEB-INF目錄上一級)下有該檔案
String absolutePath = application.getRealPath("/index.html");
}
結果
測試void setAttribute(String name, Object object)和Object getAttribute(String name)方法,新建一個entity包,裡面先新建一個實體使用者類,程式碼如下
package com.entity;
public class User {
private String usercode;
private String username;
public String getUsercode() {
return usercode;
}
public void setUsercode(String usercode) {
this.usercode = usercode;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
我們在
AServlet
類的service方法中用void setAttribute(String name, Object object)方法向ServletContext新增User物件中成員變數的資料。程式碼如下
//建立User物件,並且給成員變數賦值
User user = new User();
user.setUsercode("12335");
user.setUsername("高比例");
//給ServletContext範圍儲存資料
application.setAttribute("userObj",user);
我們在
***BServlet***
類的service方法中用Object getAttribute(String name)方法向ServletContext物件用name獲取資料。
具體程式碼如下
//ServletContext物件範圍中讀取資料
Object value = application.getAttribute("usercode");
servletResponse.getWriter().print(value);//向瀏覽器中輸出資料
寫好後部署專案執行,進入索引頁,當我們點即測試AServlet後返回頁面再點選測試BServlet,可以看到如下結果輸出
先點擊向ServletContext範圍儲存資料的資源的執行結果,再點選獲取資料的資源類執行結果,可以得到如下輸出結果
以上操作順序相反,當先點選下面連接獲取不到資料,因為還沒有存,得到如下執行結果