ServletContext的总结:
①什么是ServletContext呢?
首先我们来其API给的解释:Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
这是一个用于和servlet容器交流的的servlet类,它定义一个方法的集合。例如获得文件的类型,分派调遣request对象 或者写一个日志文件。
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.)
java虚拟机的每一个web应用都有一个servletcontext上下文对象。(一个web应用是servlet的集合和一个被安装在服务器的url命名空间下具体的子集的上下文,例如/catalog和可能被安装取道一个.war文件)
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
至于一个web应用被标记为分布式在他的部署描述器中,每一个虚拟机器将会有一个上下文实例。在这种情况下,下文不能被用来当作一个分享全面信息的场所。(因为信息不将是真正的全的)使用一个额外的资源例如数据库代替。
The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized.
上下文对象被包含在servletconfig对象中的,web服务器提供一个servletcontext当这个servlet被初始化
可能看官方网站的API有点模糊,其实总结下来也就是一下几点:
(1)servletContext就是代表web应用的一个servlet类。也就是说一个web应用只有一个servletContext对象。
(2)servletContext是用来管理web应用下的资源的。
(3)servletContext是可以被所有访问其代表web应用的用户共享的。
(4)servletContext是在服务器端被创建和销毁的。
②servletContext的生命周期
在web应用被创建时创建与其对用的servletContext,在其管理的web应用被关闭时servletContext也被销毁。所以servletcontext中的数据会长时间的保存在服务器内存中,因此最后不要往servletcontext中存储过大的数据,以免降低服务器的运行效率。
③那么我们如何获得servletContext呢?
在servlet类中获得servletContext主要有两种方式:
(1)通过this.getServletContext()方法获得上下文的引用。
(2)通过servletConfig.getServletContext()方法获得上下文的引用。
这两种方式都能获得servletContext引用。并且没有任何区别。
④ServletContext的应用场景有哪些呢?
(1)多个Servlet类通过ServletContext实现数据的共享。
(2)获得web应用的初始化参数。之前学习Servlet时就会给一个Servlet配置初始化参数。
servlet初始化参数配置如下:
<servlet>
<servlet-name>注册名</servlet-name>
<servlet-class>类路径</servlet-class>
<init-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</init-param>
<servlet>
<servlet-mapping>
<servlet-name>注册名</servlet-name>
<url-pattern>访问地址</url-pattern>
<servlet-mapping>
如果给web应用配置初始化参数或者说是让web应用下的所有servlet都可以获得该初始化参数则应该这样配置初始化参数
<context-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</context-param>
那么我们应该如何来获得给web应用配置的初始化参数呢?
其实很简单就是通过我们的ServletContext对象来获得初始化参数的。
①什么是ServletContext呢?
首先我们来其API给的解释:Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
这是一个用于和servlet容器交流的的servlet类,它定义一个方法的集合。例如获得文件的类型,分派调遣request对象 或者写一个日志文件。
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.)
java虚拟机的每一个web应用都有一个servletcontext上下文对象。(一个web应用是servlet的集合和一个被安装在服务器的url命名空间下具体的子集的上下文,例如/catalog和可能被安装取道一个.war文件)
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
至于一个web应用被标记为分布式在他的部署描述器中,每一个虚拟机器将会有一个上下文实例。在这种情况下,下文不能被用来当作一个分享全面信息的场所。(因为信息不将是真正的全的)使用一个额外的资源例如数据库代替。
The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized.
上下文对象被包含在servletconfig对象中的,web服务器提供一个servletcontext当这个servlet被初始化
可能看官方网站的API有点模糊,其实总结下来也就是一下几点:
(1)servletContext就是代表web应用的一个servlet类。也就是说一个web应用只有一个servletContext对象。
(2)servletContext是用来管理web应用下的资源的。
(3)servletContext是可以被所有访问其代表web应用的用户共享的。
(4)servletContext是在服务器端被创建和销毁的。
②servletContext的生命周期
在web应用被创建时创建与其对用的servletContext,在其管理的web应用被关闭时servletContext也被销毁。所以servletcontext中的数据会长时间的保存在服务器内存中,因此最后不要往servletcontext中存储过大的数据,以免降低服务器的运行效率。
③那么我们如何获得servletContext呢?
在servlet类中获得servletContext主要有两种方式:
(1)通过this.getServletContext()方法获得上下文的引用。
(2)通过servletConfig.getServletContext()方法获得上下文的引用。
这两种方式都能获得servletContext引用。并且没有任何区别。
④ServletContext的应用场景有哪些呢?
(1)多个Servlet类通过ServletContext实现数据的共享。
(2)获得web应用的初始化参数。之前学习Servlet时就会给一个Servlet配置初始化参数。
servlet初始化参数配置如下:
<servlet>
<servlet-name>注册名</servlet-name>
<servlet-class>类路径</servlet-class>
<init-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</init-param>
<servlet>
<servlet-mapping>
<servlet-name>注册名</servlet-name>
<url-pattern>访问地址</url-pattern>
<servlet-mapping>
如果给web应用配置初始化参数或者说是让web应用下的所有servlet都可以获得该初始化参数则应该这样配置初始化参数
<context-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</context-param>
那么我们应该如何来获得给web应用配置的初始化参数呢?
其实很简单就是通过我们的ServletContext对象来获得初始化参数的。
给我们的web应用配置初始化参数如下:
获得参数的java代码如下:
package com.yd.serlvlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
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 ReadAttribute
*/
@WebServlet("/ReadAttribute")
public class ReadAttribute extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ReadAttribute() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获得上下文对象获得设置的属性
ServletContext servletContext=this.getServletConfig().getServletContext();
String name=(String) servletContext.getAttribute("name");
//显示到网页上
PrintWriter out=response.getWriter();
out.println("没有移除属性之前name属性的值是:"+name);
//移除name属性
servletContext.removeAttribute("name");
String name2=(String) servletContext.getAttribute("name");
out.println("移除属性之后name属性的值是:"+name2);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
(3)实现servlet转发,通过ServletContext可以实现页面的转发,和我们的request.getRequestDispatcher("资源名").forward(request,response);的用法一样。可以共享request对象,也是在服务器中发生页面跳转,只能访问该web应用下的资源。
java代码如下:
package com.yd.serlvlet;
import java.io.IOException;
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 Forward
*/
@WebServlet("/Forward")
public class Forward extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Forward() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接转发
request.setCharacterEncoding("utf-8");
//给request对象添加属性
request.setAttribute("age", 18);
//通过servletcontext实现转发
this.getServletConfig().getServletContext().getRequestDispatcher("/GetInitParam").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
package com.yd.serlvlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
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 GetInitParam
*/
@WebServlet("/GetInitParam")
public class GetInitParam extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public GetInitParam() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获得参数
ServletContext servletContext=this.getServletContext();
String name=servletContext.getInitParameter("name");
PrintWriter out=response.getWriter();
//获得请求对象的属性
Integer age=(Integer) request.getAttribute("age");
out.println("初始化参数name的值:"+name+"request的属性age:"+age);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
运行结果如下:
(4)因为之前我们就说过servletContext是用来管理整个web应用的,所以可以通过servletContext来读取web应用下的资源文件。但是这里需要注意的是读取的web应用资源只能是webcontent下的资源不能是src目录下的资源。要想读取src下的资源需要通过类加载器。并且获得src资源时一定要注意资源地址包含在哪个包下,资源之间用/隔开。否则就不能正确的访问到src下的文件。
java代码如下:
package com.yd.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.corba.se.spi.orbutil.fsm.Input;
/**
* Servlet implementation class GetResource
*/
@WebServlet("/GetResource")
public class GetResource extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public GetResource() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应对象
response.setContentType("text/html;charset=utf-8");
//首先获得上下文对象
ServletContext servletContext=this.getServletContext();
//以流的形式获得资源
InputStream is=servletContext.getResourceAsStream("/properties/count.properties");
//将流作为参数放大属性对象中
Properties properties=new Properties();
properties.load(is);
//获得属性对象中的键值
PrintWriter out=response.getWriter();
out.println("获得属性对象中的值username:"+properties.getProperty("count")+"<br/>");
//如果要获得src下资源需要使用类加载器
InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("/com/yd/serlvlet/dbinfo.properties");
Properties properties2=new Properties();
properties2.load(inputStream);
System.out.println(properties2);
out.println("src获得属性对象中的值username:"+properties2.getProperty("username"));
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
文件内容截图如下:
运行结果如图:
(5)获得资源在服务器的绝对路径。这个对于项目部署的服务器中要找到一个资源是很有用的。
java代码如下:
package com.yd.serlvlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.ServletContext;
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 GetRealPath
*/
@WebServlet("/GetRealPath")
public class GetRealPath extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public GetRealPath() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应对象的响应文件类型
response.setContentType("text/html;charset=utf-8");
//获取上下文对象
ServletContext servletContext=this.getServletContext();
//获得资源在服务器的位置
String path=servletContext.getRealPath("/image/context初始化参数.png");
//获得资源的url
URL url=servletContext.getResource("/image/context初始化参数.png");
PrintWriter out=response.getWriter();
out.println("服务器位置path="+path+"<br/>");
out.println("url="+url.getPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
运行结果如下: