JAVAWeb06-动态WEB开发核心Servlet-02-ServletConfig/Context
1. ServletConfig
1.1 ServletConfig 基本介绍
- ServletConfig 类是为 Servlet 程序的配置信息的类
- Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建
- Servlet 程序默认是第 1 次访问的时候创建,ServletConfig 在 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象
1.2 ServletConfig 类能干什么
- 获取 Servlet 程序的 servlet-name 的值
- 获取初始化参数 init-param
- 获取 ServletContext 对象
1.3 ServletConfig 应用实例
● 需求: 编写 DBServlet.java 完成如下功能
- 在 web.xml 配置连接 mysql 的用户名和密码
- 在 DBServlet 执行 doGet()/doPost() 时,可以获取到 web.xml 配置的用户名和密码
- 示意图(思路分析)
● 代码实现
提示:具体看项目对应的代码
DBServlet.java
public class DBServlet extends HttpServlet {/*** 老师梳理ServletConfig config 使用流程* 1. 当DBServlet对象初始化时, tomcat会同时创建一个 ServletConfig对象* 2. 这时如果DBServlet init() 方法中你调用 super.init(config);* 3. 调用 父类 GenericServlet* public void init(ServletConfig config) throws ServletException {* this.config = config;* this.init();* }* 这时就会把 Tomcat创建的 ServletConfig对象赋给 GenericServlet的属性 config* 4. 因此如果你重写init()方法,记住如果你想在其它方法通过 getServletConfig() 方法获取ServletConfig* , 则一定要记住 调用 super.init(config);* @param config* @throws ServletException*/@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("init" + config);super.init(config);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//在DBServlet 执行 doGet()/doPost() 时,可以获取到web.xml配置的用户名和密码//你是一个OOP程序员->现有的方法或对象来搞定//DBServlet的父类GenericServlet有getServletConfig()/*** 解读* 1. getServletConfig() 方法是 GenericServlet* 2. 返回的 servletConfig对象是 GenericServlet private transient ServletConfig config;* 3. 当一个属性被 transient 修饰,表示该属性不会被串行化(有些重要信息,不希望保存到文件)*/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);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
xml文件
<servlet><servlet-name>DBServlet</servlet-name><servlet-class>com.hspedu.servlet.DBServlet</servlet-class><!--配置信息,而不是硬编码到程序--><init-param><param-name>username</param-name><param-value>hsp</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>
优化:注解方式实现
@WebServlet(name = "DBServlet2", value = "/DBServlet2",initParams = {@WebInitParam(name = "user",value = "root"),@WebInitParam(name = "pwd",value = "123456")})
public class DBServlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletConfig servletConfig = getServletConfig();String user = servletConfig.getInitParameter("user");String pwd = servletConfig.getInitParameter("pwd");System.out.println("user:"+user);System.out.println("pwd:"+pwd);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}
}
2. ServletContext
2.1 为什么需要 ServletContext
- 先看一个需求: 如果我们希望统计某个 web 应用的所有 Servlet 被访问的次数,怎么办?
- 方案 1-DB
- 方案 2-ServletContext
2.2 ServletContext 基本介绍
- ServletContext 是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,只有一个 ServletContext 对象实例
- ServletContext 对象 是在 web 工程启动的时候创建,在 web 工程停止的时销毁
- ServletContext 对象可以通过 ServletConfig.getServletContext 方法获得对 ServletContext
对象的引用,也可以通过 this.getServletContext()来获得其对象的引用。 - 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象之间可以通过 ServletContext 对象来实现多个 Servlet 间通讯。ServletContext 对象通常也被称之为域对象。【示意图】
2.3 ServletContext 可以做什么
- 获取 web.xml 中配置的上下文参数 context-param [信息和整个 web 应用相关,而不是
属于某个 Servlet] - 获取当前的工程路径,格式: /工程路径 =》 比如 /servlet
- 获 取 工 程 部 署 后 在 服 务 器 硬 盘 上 的 绝 对 路 径 ( 比 如
D:\\hspedu_javaweb\\servlet\\out\\artifacts\\servlet_war_exploded)
- 像 Map 一样存取数据, 多个 Servlet 共享数据
2.4 应用实例
2.4.1 应用实例 1-获取工程相关信息
● 需求如下:
- 获取 web.xml 中配置的上下文参数 context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
● 代码实现 - 具体看 项目中的代码.
ServletContext_.java
public class ServletContext_ extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取web.xml的context-parameter//1.1 获取到ServletContext对象 方式1// ServletContext servletContext = servletConfig.getServletContext();//1.2 获取到ServletContext对象ServletContext servletContext = getServletContext();//2. 获取websiteString website = servletContext.getInitParameter("website");String company = servletContext.getInitParameter("company");//3. 获取项目的工程路径String contextPath = servletContext.getContextPath();//4. 获取项目发布后,正在的工作路径// /表示我们的项目(发布后)的 根路径 D:\\hspedu_javaweb\\servlet\\out\\artifacts\\servlet_war_explodedString realPath = servletContext.getRealPath("/");System.out.println("项目路径= " + contextPath);// /servletSystem.out.println("website= " + website);System.out.println("company= " + company);System.out.println("项目发布后的绝对路径= " + realPath);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
web.xml
<!--配置ServletContext_-->
<servlet><servlet-name>ServletContext_</servlet-name><servlet-class>com.hspedu.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.baidu.com</param-value>
</context-param>
<context-param><param-name>company</param-name><param-value>百度</param-value>
</context-param>
2.4.2 应用实例 2-简单的网站访问次数计数器
需求分析/图解
- 需求: 完成一个简单的网站访问次数计数器:
- 使用 Chrome 访问 Servlet01, 每访问一次,就增加 1 访问次数,在后台输出,并将结果返回给浏览器显示
- 使用火狐访问 Servlet02,每访问一次,就增加 1 访问次数,在后台输出,并将结果返回给浏览器显示
OrderServlet.java
public class OrderServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取到ServletContext对象ServletContext servletContext = getServletContext();// System.out.println("OrderServlet servletContext= " +// servletContext + " 运行类型=" + servletContext.getClass());// 法1// //从servletContext获取 visit_count 属性 k-v// Object visit_count = servletContext.getAttribute("visit_count");// //判断visit_count是否为null// 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);// }// 法2Integer 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();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
PayServlet.java
public class PayServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取到ServletContext对象ServletContext servletContext = getServletContext();// System.out.println("PayServlet servletContext= " +// servletContext + " 运行类型=" + servletContext.getClass());//法1// //从servletContext获取 visit_count 属性 k-v// Object visit_count = servletContext.getAttribute("visit_count");// //判断visit_count是否为null// 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);// }//法2Integer 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();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
创 建 工 具 类 WebUtils.java
public class WebUtils {//这个方法就是对访问的次数累积,同时返回次数public static Integer visitCount(ServletContext servletContext) {//从servletContext获取 visit_count 属性 k-vObject visit_count = servletContext.getAttribute("visit_count");//判断visit_count是否为nullif (visit_count == null) {//说明是第1次访问网站servletContext.setAttribute("visit_count", 1);visit_count = 1;} else { //是第二次或以后//取出visit_count属性的值+1visit_count = Integer.parseInt(visit_count + "") + 1;//放回到servletContextservletContext.setAttribute("visit_count", visit_count);}return Integer.parseInt(visit_count + "");}
}
在 web.xml 中配置两个 servlet
<servlet><servlet-name>OrderServlet</servlet-name><servlet-class>com.hspedu.servlet.servletcontext.OrderServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>OrderServlet</servlet-name><url-pattern>/orderServlet</url-pattern>
</servlet-mapping><servlet><servlet-name>PayServlet</servlet-name><servlet-class>com.hspedu.servlet.servletcontext.PayServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>PayServlet</servlet-name><url-pattern>/payServlet</url-pattern>
</servlet-mapping>
完成测试