目录
一、ServletConfig
1.基本介绍 :
- ServletConfig类是为Servlet程序的配置信息的类;
- Servlet程序和ServletConfig对象都是由Tomcat负责创建;
- Servlet程序默认是在第1次访问的时候被创建,ServletConfig则是Tomcat在创建servlet实例时,同时创建一个对应的ServletConfig对象。
2.基本功能 :
- 获取Servlet程序的servlet-name的值
- 获取初始化参数init-param
- 获取ServletContext对象
3.应用实例 :
编写DBServlet类,要求该servlet可以获取到web.xml配置文件中的数据库登录信息。
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>DBServlet</servlet-name> <servlet-class>db.DBServlet</servlet-class> <init-param> <param-name>username</param-name> <param-value>Five</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>12345</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DBServlet</servlet-name> <url-pattern>/dBServlet</url-pattern> </servlet-mapping> </web-app>
DBServlet代码如下 :
package db; import jakarta.servlet.ServletConfig; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author : Cyan_RA9 * @version : 21.0 */ public class DBServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* 直接父类HttpServlet中没有getServletConfig方法,因此要向再上一层的父类GenericServlet中找。 最终返回的就是GenericServlet中的config属性。 */ ServletConfig servletConfig = getServletConfig(); String username = servletConfig.getInitParameter("username"); String password = servletConfig.getInitParameter("password"); System.out.println(("Init-Param username = " + username)); System.out.println(("Init-Param password = " + password)); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
运行效果 : (如下GIF图)
编辑
4.细节补充 :
当Servlet实例被创建时,Tomcat会同时创建一个对应的ServletConfig对象。
此时,如果重写了init方法,必须定义super.init(config);语句,这时Tomcat就会把创建的ServletConfig对象作为实参传递到init方法的形参列表,并通过super语句最终将该ServletConfig实例赋值给GenericServlet类的config属性。
eg :
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}如此一来,才能在其他方法中通过getServletConfig方法获取到正确的config属性。
二、ServletContext
1.基本介绍 :
- ServletContext是一个接口,表示Servlet上下文对象。
- 一个web工程,只有一个ServletContext对象实例;ServletContext对象是在web工程启动的时候创建,在web工程终止的时销毁。
- 获取ServletContext对象既可以通过ServletConfig.getServletContext();也可以直接通过this.getServletContext(),来获得其对象的引用。
- 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现多个Servlet间通讯。ServletContext对象通常也被称之为域对象。
PS :
ServletContext对象的数据存储形式为key-value键值对,类似于Map集合。
2.基本功能 :
- 获取web.xml中配置的上下文参数context-param(整个web应用相关,而不是属于某个Servlet)
- 动态地获取当前的工程路径(Application Context),格式 :/工程路径
- 获取工程部署后,在服务器硬盘上的绝对路径(out目录)
- 像Map集合一样存取数据(keg-value键值对),且同一Web应用下的多个Servlet,共享ServletContext对象的数据
3.获取Web工程相关信息 :
定义一个servlet,要求该servlet可以获取到当前Web应用的相关信息(上下文参数、项目路径、实际工作路径)
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>ProjectServlet</servlet-name> <servlet-class>middle.ProjectServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ProjectServlet</servlet-name> <url-pattern>/psToGetInfo</url-pattern> </servlet-mapping> <!--配置整个Web应用的相关信息--> <context-param> <param-name>website</param-name> <param-value>https://blog.csdn.net/TYRA9?spm=1010.2135.3001.5343</param-value> </context-param> <context-param> <param-name>blogger</param-name> <param-value>Cyan_RA9</param-value> </context-param> </web-app>
ProjectServlet代码如下 :
package middle; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author : Cyan_RA9 * @version : 21.0 */ public class ProjectServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取ServletContext对象 ServletContext servletContext = this.getServletContext(); //2.获取web.xml中配置的上下文参数 String website = servletContext.getInitParameter("website"); String blogger = servletContext.getInitParameter("blogger"); System.out.println("website = " + website); System.out.println("blogger = " + blogger); //3.获取整个Web应用的项目路径 String contextPath = servletContext.getContextPath(); System.out.println("contextPath = " + contextPath); //4.获取工程部署后,在磁盘的绝对路径(实际工作时访问的路径) // "/"表示项目(部署后)的根路径 String realPath = servletContext.getRealPath("/"); System.out.println("realPath = " + realPath); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
运行效果:(如下GIF图)
编辑
4.网页访问计数器 :
1° 代码实现
要求统计某一个Web工程下所有servlet累计被访问的次数,并将该次数以标题形式返回给浏览器。
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>CountServlet</servlet-name> <servlet-class>middle.CountServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/countServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>CountServlet_EX</servlet-name> <servlet-class>middle.CountServlet_EX</servlet-class> </servlet> <servlet-mapping> <servlet-name>CountServlet_EX</servlet-name> <url-pattern>/countServletEX</url-pattern> </servlet-mapping> </web-app>
分别定义CountServlet和CountServlet_EX两个servlet进行模拟;
CountServlet代码如下 :
package middle; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class CountServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); System.out.println("servletContext = " + servletContext); System.out.println("servletContext's runtime Class = " + servletContext.getClass()); System.out.println("=========================================="); Object visits = servletContext.getAttribute("visits"); if (visits == null) { //说明是第一次访问该Web工程 servletContext.setAttribute("visits", 1); visits = 1; } else { //说明是非首次访问该Web工程 visits = Integer.parseInt(visits + "") + 1; servletContext.setAttribute("visits", visits); } resp.setContentType("text/html; charset=utf-8"); PrintWriter writer = resp.getWriter(); writer.print("<h1>网站被访问了" + visits + "次了捏🤗</h1>"); writer.flush(); writer.close(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
CountServlet_EX代码如下 :
package middle; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class CountServlet_EX extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); System.out.println("servletContext_EX = " + servletContext); System.out.println("servletContext_EX's runtime Class = " + servletContext.getClass()); System.out.println("-----------------------------------------------"); Object visits = servletContext.getAttribute("visits"); if (visits == null) { servletContext.setAttribute("visits", 1); visits = 1; } else { visits = Integer.parseInt(visits + "") + 1; servletContext.setAttribute("visits", visits); } resp.setContentType("text/html; charset=utf-8"); PrintWriter writer = resp.getWriter(); writer.print("<h1>网站被访问了" + visits + "次了捏🤗</h1>"); //保险起见! writer.flush(); writer.close(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
运行效果 : (如下GIF图)
编辑
在IDEA中可以看到,两个servlet使用的ServletContext对象是同一个,如下图所示 :
编辑
2° 代码优化
可以将CountServlet和CountServlet_EX中重复冗余的代码封装到一个工具类中,在该工具类中定义静态方法,用于返回网站被访问的总次数。
WebUtils类代码如下 :
package middle; import jakarta.servlet.ServletContext; public class WebUtils { public static Integer visitCount(ServletContext servletContext) { Object visits = servletContext.getAttribute("visits"); if (visits == null) { servletContext.setAttribute("visits", 1); visits = 1; } else { visits = Integer.parseInt(visits + "") + 1; servletContext.setAttribute("visits", visits); } return Integer.parseInt(visits + ""); } }
接着,在CountServlet和CountServlet_EX类中去调用visitCount静态方法即可,如下图所示 :
编辑
运行效果 :(如下GIF图)
编辑
三、Servlet(中)总结
(1) 熟悉ServletConfig创建的时机 (Tomcat在创建Servlet实例时创建其对应的ServletConfig;最终使用的是GenericServlet中的config属性);
(2)掌握ServletConfig的API(获取定义在<servlet></servlet>中的初始化参数);
(3) 熟悉ServletContext的特性(一个Web工程仅对应一个ServletContext对象);
(4)熟悉ServletContext的功能(获取Web应用的上下文参数;获取工程路径;获取工程部署后的绝对路径;作为同一Web工程下servlet的共享数据的容器)
(5) 掌握ServletContext对象获取Web项目信息的API (getInitParameter, getContextPath, getRealPath);
(6) 掌握ServletContext对象操作属性的API (getAttribute, setAttribute)。
System.out.println("END------------------------------------------------------------------------------");