Servlet04
12.ServletConfig
12.1ServletConfig基本介紹
- ServletConfig類是為Servlet程式配置資訊的類
- Servlet物件和ServletConfig物件都是由Tomcat負責創建
- Servlet物件默認是第一次訪問的時候創建,ServletConfig在Servlet物件創建的時候,就創建一個對應的ServletConfig物件
12.2ServletConfig作用
- 獲取Servlet程式的servlet-name的值
- 獲取初始化引數init-param
- 獲取ServletContext物件(背景關系物件)
12.3ServletConfig應用實體
例子
需求:撰寫DBServlet.java,完成如下功能
-
在web.xml配置連接mysql的用戶名和密碼
-
在DBServlet執行doGet()或者doPost()時,可以獲取到web.xml配置的用戶名和密碼
-
思路分析:
瀏覽器發送請求,Tomcat去創建DBServlet,DBServlet去web.xml檔案中去獲取配置的引數,獲取的方法有兩種:一是使用dom4j,二是使用ServletConfig類
web.xml配置Servlet:
<!--配置DBServlet-->
<servlet>
<servlet-name>DBServlet</servlet-name>
<servlet-class>servlet.DBServlet</servlet-class>
<!--為該Servlet配置初始引數-->
<init-param>
<!--引數名-->
<param-name>username</param-name>
<!--引數值-->
<param-value>jack</param-value>
</init-param>
<init-param>
<param-name>pwd</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DBServlet</servlet-name>
<url-pattern>/db</url-pattern>
</servlet-mapping>
DBServlet:
package servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class DBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在DBServlet執行doGet()或者doPost()時,可以獲取到web.xml配置的用戶名和密碼
//DBServlet的父類GenericServlet有方法getServletConfig()
/**
* 1.getServletConfig()是父類GenericServlet的
* 2.回傳的ServletConfig物件是GenericServlet的private transient ServletConfig config
* 3.當一個屬性被transient修飾,表示該屬性不會被串行化(有些重要資訊不希望保存到檔案中)
*/
ServletConfig servletConfig = getServletConfig();
String username = servletConfig.getInitParameter("username");
String pwd = servletConfig.getInitParameter("pwd");
System.out.println("初始化引數username=" + username);
System.out.println("初始化引數pwd=" + pwd);
}
}
瀏覽器訪問DBServlet時,后臺輸出:
問題一:在doPost方法中可以得到servletConfig,在doGet方法也可以得到servletConfig,那么這兩個servletConfig是同一個servletConfig嗎?
答:是同一個servletConfig,
先來看一個例子
在上述的DBServlet中重寫init方法,并且分別在init和doPost方法中輸出ServletConfig物件
package servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class DBServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init()=" + config);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
System.out.println("doPost()=" + servletConfig);
String username = servletConfig.getInitParameter("username");
String pwd = servletConfig.getInitParameter("pwd");
System.out.println("初始化引數username=" + username);
System.out.println("初始化引數pwd=" + pwd);
}
}
redeployTomcat,在瀏覽器重新訪問DBServlet,會發現出現了500錯誤,這表明服務器內部運行出現錯誤
查看控制臺輸出,發現doPost方法竟然輸出了null
在DBServlet中的init方法加上陳述句super.init(config);
redeployTomcat,重新訪問瀏覽器,會發現訪問DBServlet成功,后臺輸出變正常了
問題二:這是為什么呢?
我們先來梳理ServletConfig config的使用流程
-
當DBServlet物件初始化時,Tomcat會同時創建一個ServletConfig物件
-
如果DBServlet init()方法中呼叫了super.init(config);
-
就會呼叫父類GenericServlet的init方法:
public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); }這時就會把Tomcat創建的ServletConfig物件賦給GenericServlet的屬性config
-
因此如果要重寫init()方法,記住如果你想在其他方法通過getServletConfig()獲取ServletConfig,則一定要記住呼叫super.init(config);
回到問題二:
如果沒有把tomcat創建的ServletConfig,賦值給GenericServlet的屬性config,那么GenericServlet的屬性config的值就為null,而doPost或者doGet方法通過getServletConfig()拿到的就是GenericServlet的屬性config,因此就會輸出null,
側面證實了方法中獲取的servletConfig是同一個物件(問題一)
因此上面的例子中,瀏覽器訪問DBServlet,發現出現了500錯誤的原因是,doPost方法中獲取了為null的ServletConfig物件中的屬性
13.ServletContext
13.1為什么需要ServletContext
先來看一個需求:如果我們希望統計某個web應用的所有Servlet被訪問的次數,怎么辦?
方案一:使用DB
方案二:使用ServletContext
13.2ServletContext基本介紹
-
ServletContext是一個介面,它表示Servlet背景關系物件
-
一個web工程中,只有一個ServletContext物件實體
-
ServletContext物件是在web工程啟動的時候創建的,在web工程停止的時候銷毀
-
可以通過ServletConfig.getServletContext方法獲得對ServletContext物件的應用,也可以通過this.getServletContext()來獲得其物件的參考
-
由于一個web應用中的所有Servlet共享一個ServletContext物件,因此Servlet物件之間可以通過ServletContext物件來實作多個Servlet間的通信,ServletContext物件通常也被稱為域物件,
13.3ServletContext可以做什么
-
獲取web.xml檔案中配置的背景關系引數context-param [資訊和整個web應用相關,而不是屬于某個Servlet]
-
獲取當前的工程路徑,格式:/工程路徑
-
獲取工程部署后在服務器硬碟上的絕對路徑
比如 D:\IDEA-workspace\servlet\out\artifacts\servlet_war_exploded
-
向Map一樣存取資料,多個Servlet共享資料
13.4應用實體
13.4.1應用實體1-獲取工程相關資訊
需求如下:
- 獲取web.xml中配置的背景關系引數context-param
- 獲取當前的工程路徑,格式:/工程路徑
- 獲取工程部署后在服務器硬碟上的絕對路徑
配置ServletContext_: 在web.xml檔案增加相關配置
<!--配置ServletContext_-->
<servlet>
<servlet-name>ServletContext_</servlet-name>
<servlet-class>com.li.servlet.servletcontext.ServletContext_</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletContext_</servlet-name>
<url-pattern>/servletContext_</url-pattern>
</servlet-mapping>
<!--配置整個網站的資訊-->
<context-param>
<param-name>website</param-name>
<param-value>http://www.lili.net</param-value>
</context-param>
<context-param>
<param-name>company</param-name>
<param-value>lili有限公司</param-value>
</context-param>
ServletContext_:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class ServletContext_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取web.xml的context-parameter
//1.獲取到ServletContext物件
ServletContext servletContext = getServletContext();
//2.獲取website
String website = servletContext.getInitParameter("website");
String company = servletContext.getInitParameter("company");
System.out.println("website= " + website);
System.out.println("company= " + company);
//3.獲取專案的工程路徑
String contextPath = servletContext.getContextPath();
System.out.println("專案路徑= " + contextPath);// /servlet_demo
//4.得到專案發布后真正的作業路徑
//這里的斜杠/表示我們的專案發布后的根路徑 D:\IDEA-workspace\servlet_demo\out\artifacts\servlet_demo_war_exploded
String realPath = servletContext.getRealPath("/");
System.out.println("專案發布后的絕對路徑= " + realPath);
}
}
瀏覽器訪問ServletContext_:
后臺輸出:
13.4.2應用實體2-簡單的網站訪問次數統計器
需求:完成一個簡單的網站訪問次數統計器
不管使用什么瀏覽器,每訪問一次Servlet,就增加1訪問次數,在后臺輸出,并將結果回傳給瀏覽器顯示
WebUtils.java:
package com.li.servlet.servletcontext;
import javax.servlet.ServletContext;
public class WebUtils {
//該方法對訪問網站的次數累加,同時回傳次數
public static Integer visitCount(ServletContext servletContext) {
//從servletContext獲取 visit_count 屬性 k-v
Object visit_count = servletContext.getAttribute("visit_count");
//判斷visit_count是否為空
if (visit_count == null) {//說明是第1次訪問網站
servletContext.setAttribute("visit_count", 1);
visit_count = 1;
} else {//說明是第二次或之后訪問
//visit_count+1
visit_count = Integer.parseInt(visit_count + "") + 1;
//再將其放回servletContext
servletContext.setAttribute("visit_count", visit_count);
}
return Integer.parseInt(visit_count + "");
}
}
Servlet01.java:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/Servlet01"})
public class Servlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取到ServletContext物件
ServletContext servletContext = getServletContext();
Integer visit_count = WebUtils.visitCount(servletContext);
//輸出顯示
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>該網站被訪問的次數是" + visit_count + "</h1>");
writer.flush();
writer.close();
}
}
Servlet02.java:
package com.li.servlet.servletcontext;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/Servlet02"})
public class Servlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲取到ServletContext物件
ServletContext servletContext = getServletContext();
Integer visit_count = WebUtils.visitCount(servletContext);
//輸出顯示
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print("<h1>該網站被訪問的次數是" + visit_count + "</h1>");
writer.flush();
writer.close();
}
}
redeployTomcat,在不同的瀏覽器分別訪問Servlet01和Servlet02:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/531817.html
標籤:其他
