ServletConfig,ServletContext详细讲解
1. ServletConfig
Servlet是开发动态web的技术,而web.xml是Tomcat工程中最基础也最重要的配置文件,Tomcat启动项目的时候会加载并读取这个文件,其中web.xml中在servlet标签中会有关于servlet的配置,可以使用一个或多个<init-param></init-param>标签为servlet配置一些初始化参数。
1.1 如下为servlet配置一些初始化参数。
1.2 通过ServletConfig获取servlet的初始化参数
可以通过如下程序获得servlet的初始化参数。
package MyServletDemo; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; //import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class MyServletDemo */ //@WebServlet("/ServletDemo1") public class ServletDemo1 extends HttpServlet { private ServletConfig config; @Override public void init(ServletConfig config) throws ServletException { this.config = config; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取在web.xml中配置的初始化参数 String paramVal = this.config.getInitParameter("name");//获取指定的初始化参数 response.getWriter().print(paramVal); response.getWriter().print("<hr/>"); //获取所有的初始化参数 Enumeration<String> e = config.getInitParameterNames(); while(e.hasMoreElements()){ String name = e.nextElement(); String value = config.getInitParameter(name); response.getWriter().print(name + "=" + value + "<br/>"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,我们通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
运行后显示以下结果。
需要注意,在servlet3.0之后的版本,可以通过@WebServlet直接映射,即@WebServlet相当于web.xml中的<servlet-mapping></servlet-mapping>这个标签的作用。在上面的获取servlet的初始化参数的例子中,已经在web.xml中有了<servlet-mapping></servlet-mapping>这个映射标签,所以ServletDemo1.java这个程序中就不需要再使用@WebServlet("/ServletDemo1")了。
2. ServletContext对象
2.1 为什么需要ServletContext?
①访问某个网站时候,往往都会看到网站的首页面显示您是第几位浏览者(网站计数器),这是如何实现的?
②显示论坛在线人数
2.2 什么是ServletContext?
要理解ServletContext先来和cookie,session做一个对比。
- cookie:是指存储在客户端上的信息,浏览器一旦关闭cookie就被清除。每个用户都有独立的存储cookie的空间,互相独立,只能自己访问自己的cookie。
- session:是指存储在服务器端的信息。每个用户都有独立的存储session的空间,互相独立,只能自己访问自己的session。
- servletContext:servletContext接口是Servlet中最大的一个接口,呈现了web应用的Servlet视图。ServletContext实例是通过 getServletContext()方法获得的,由于HttpServlet继承GenericServlet的关系,GenericServlet类和HttpServlet类同时具有该方法。所有用户都可以访问servletContext,比如说我用谷歌给ServletContext 传递了信息,不仅在谷歌页面能获得ServletContext中的信息,在IE浏览器输入正确的网址也能得到ServletContext中的信息。
下图可以很好的说明他们之间的关系。
什么是ServletContext?
- ServletContext是一个用于和servlet容器交流的servlet类,它定义一个方法的集合,例如获得文件的类型,分派调遣request对象或者写一个日志文件。
- web容器在启动时,它会为每个web应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
- ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig().getServletContext()方法获得ServletContext对象。
- 由于一个web应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
2.3 ServletContext的应用
2.3.1 多个servlet通过ServletContext对象实现数据共享
上面提到过servlet之间可以通过ServletContext对象来实现通讯,下面两个程序ServletContextDemo1和ServletContextDemo2通过ServletContext对象实现了数据共享。
ServletContextDemo1.java
package MyServletDemo; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletContextDemo1 extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ String data = "servletcontextdemodata"; //通过ServletConfig.getServletContext方法获得ServletContext对象 ServletContext context = this.getServletConfig().getServletContext(); //将data存储到ServletContext对象中 context.setAttribute("data", data); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
ServletContextDemo2.java
package MyServletDemo; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletContextDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); //从ServletContext对象中取出数据 String data = (String) context.getAttribute("data"); response.getWriter().print("data="+data); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
先运行ServletContextDemo1,将数据data存储到ServletContext对象中,然后运行ServletContextDemo2就可以从ServletContext对象中取出数据了,这样就实现了数据共享,如下图所示:
注意要在web.xml中进行配置:
2.3.2 通过ServletContext获取web应用的初始化参数
在web.xml文件使用<context-param>标签配置web应用的初始化参数,
编写代码ServletContextDemo3获得web的初始化参数,
package MyServletDemo; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletContextDemo3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); //获取整个web站点的初始化参数 String contextInitParam = context.getInitParameter("URL链接"); response.getWriter().print(contextInitParam); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在web.xml中进行配置servlet,
运行后显示如下结果:
2.3.3 用ServletContext实现请求转发
ServletContextDemo4.java
package MyServletDemo; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletContextDemo4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "<h1><font color='red'>servletcontextDemo4</font></h1>"; response.getOutputStream().write(data.getBytes()); //获取ServletContext对象 ServletContext context = this.getServletContext(); //获取请求转发对象(RequestDispatcher) RequestDispatcher rd = context.getRequestDispatcher("/ServletContextDemo5"); //调用forward方法实现请求转发 rd.forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
ServletContextDemo5.java
package MyServletDemo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletContextDemo5 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getOutputStream().write("servletDemo5".getBytes()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
先来看看ServletContextDemo4.java代码中的RequestDispatcher,看API帮助文档。
也就是说,RequestDispatcher定义一个对象,该对象接收来自客户端的请求,并将它们发送到服务器上的任何资源(例如servlet,HTML文件或JSP文件)。 servlet容器创建RequestDispatcher对象,该对象用作位于特定路径或由特定名称给定的服务器资源的包装器。此接口旨在包装servlet,但servlet容器可以创建RequestDispatcher对象来包装任何类型的资源。
上述代码中通过RequestDispatcher rd = context.getRequestDispatcher("/servlet/ServletContextDemo5");获取请求转发内容。
getRequestDispatcher()返回一个RequestDispatcher对象,该对象充当位于给定路径的资源的包装器。 RequestDispatcher对象可用于将请求转发到资源或将资源包含在响应中。 资源可以是动态的也可以是静态的。
路径名必须以/开头,并且被解释为相对于当前上下文根。 使用getContext为外部上下文中的资源获取RequestDispatcher。
如果ServletContext无法返回RequestDispatcher,则此方法返回null。
运行之前还是要在web.xmLl中进行配置。
运行ServletContextDemo5.java,显示如下结果:
运行ServletContextDemo4.java,实现了通过访问ServletContextDemo4,浏览器显示ServletContextDemo5的内容,也就是实现了请求转发的功能。
未完,待续。
欢迎搜索微信公众号“程序员考拉”,关注更多精彩内容!
- 如何使用Hue创建Spark2的Oozie工作流(补充)
- 如何基于CDSW基础镜像定制Docker
- OVSDB介绍及在OpenDaylight中的调用
- 如何在CDH集群的非元数据库节点安装MySQL5.7.12
- PySpark数据类型转换异常分析
- SQLI-LABS 更新帖(二)
- 如何重置Hue用户密码
- 如何使用R连接Hive与Impala
- Equation Group泄露工具之vBulletin无文件后门分析
- 如何使用CDSW在CDH集群通过sparklyr提交R的Spark作业
- 如何使用Beeline连接Impala
- 微软公式编辑器系列漏洞分析(一):CVE-2017-11882
- 预警揭秘:倒计时炸弹11.2.0.4前版本DB Link必须在2019年4月升级真相
- RPO攻击技术浅析
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 精讲RestTemplate第8篇-请求失败自动重试机制
- 精讲RestTemplate第7篇-自定义请求失败异常处理
- 精讲RestTemplate第10篇-使用代理作为跳板发送请求
- 精讲响应式WebClient第5篇-请求超时设置与异常处理
- 精讲响应式WebClient第4篇-文件上传与下载
- 【大家的项目】Rust Base62 库学习和分析
- ES2020 中 Javascript 10 个你应该知道的新功能
- Webpack5 跨应用代码共享 - Module Federation
- 【Rust日报】2020-09-16 - Rust 2021 规划
- 精讲响应式WebClient第3篇-POST、DELETE、PUT方法使用
- C++的黑魔法: 用四种方式实现add!
- 精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方法详解
- 算法篇:位运算异或的使用(一)
- 精讲响应式webclient第1篇-响应式非阻塞IO与基础用法
- k8s 二进制集群平滑升级 1.15.2升级至1.16.4