ServletContext
1. 定义
servletContext接口是Servlet中最大的一个接口,呈现了web应用的Servlet视图。ServletContext实例是通过 getServletContext()方法获得的,由于HttpServlet继承GenericServlet的关系,GenericServlet类和HttpServlet类同时具有该方法。
2. 作用
一个特定URL名字空间下的所有Servlet,JSP,JavaBean等Web部件的集合构成了一个Web的应用,每一个Web应用(同一JVM),容器都会有一个背景对象,而javax.servlet.ServletContext接口就提供了访问这个背景对象的途径。
2.1 共享数据
由于每个Servlet对象不互通,不能共享数据,所以提供了ServletContext,它就相当于是一个共享的容器,每一个servlet对象都可以到里面存取数据,如下所示。
![image-20210824163638085](https://i-blog.csdnimg.cn/blog_migrate/67c9d0bccf19a596b4029cb2e51bfc29.png)
演示:
- 首先创建一个类setContextServlet,调用时可以创建一个Servlet对象获取到ServletContext,它使用setAttribute()来给ServletContext中放入数据**(键值对形式)**
public class setContextServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
ServletContext context = this.getServletContext();
context.setAttribute("userName", "你好");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
doGet(req, resp);
}
}
-
接着创建一个类getContextServlet,调用时可以创建一个Servlet对象获取到ServletContext,它使用getAttribute(“键名”)方法,可以获取到ServletContext中对应的数据。
如果键值对中有中文需要在网页上显示,需要 设置格式为 text/html 编码为 utf-8
public class getContextServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
//防止中文乱码,设置格式为 text/html 编码为 utf-8
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
ServletContext context = this.getServletContext();
//获取ServletContext中的数据
String userName = (String) context.getAttribute("userName");
PrintWriter writer = resp.getWriter();
writer.write(userName);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
doGet(req, resp);
}
}
2.2 请求转发
当需要从一个页面获取到另一个页面处理后的数据(而不跳转到另一个页面),就需要请求转发来完成,如下所示,A需要C处理数据,就将数据发送给B(相当于转发对象),B转发数据给C,C处理后通过B再返回给A。
- 首先获取到ServletContext对象,调用其getRequestDispatcher(“转发目标url”)获取到转发对象
- 接着调用其forward(req, resp)方式完成转发
如下,转发目标为/hello**(其内容未在网页上打印 helloContextServlet )**
public class getContextServletTrans extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
//获取转发对象
RequestDispatcher requestDispatcher = this.getServletContext().getRequestDispatcher("/hello");
//转发
requestDispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
doGet(req, resp);
}
}
其mapper文件如下
<servlet>
<servlet-name>gt</servlet-name>
<servlet-class>com.zy.servlet.getContextServletTrans</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gt</servlet-name>
<url-pattern>/gt</url-pattern>
</servlet-mapping>
结果如下,访问的是 /gt 却出现了 /hello 中处理后得到的数据
这里先引入一个知识 Maven项目下资源打包
以在**源目录(java)**中创建一个 test.properties **资源根目录(resources)**中创建一个 db.properties 在为例,如下所示
![]()
>
资源根目录中的所有文件,经过Maven打包后将会在类路径下(WEB-INF/classes/),如下所示
但是在**源目录(java)中的test.properties却不见了,这是为什么呢?Maven项目在打包时,只会将源目录(java)**中的java文件编译成class文件,其他文件将直接丢弃,那么如果必须使用那些文件呢?那么就需要对Maven项目的pom.xml文件进行一些配置,如下所示,我们在pom.xml中的bulid标签中加入一下配置即可。
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
再次打包,我们发现在类路径下,已经有了test.properties文件,如下所示
![]()
2.3 读取资源文件
我们有时候需要使用到一些资源文件,这同样也需要到ServletContext对象
- 首先使用getResourceAsStream(“需要读取的文件的相对路径”)将文件变为输入流对象
- 接着将其加载到新创建的配置文件对象即可。
public class getContextServletProperties extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
//获取指定位置的文件
InputStream stream = this.getServletContext().getResourceAsStream("/WEBINF/classes/db.properties");
//创建配置文件类对象
Properties pro = new Properties();
//将配置文件流加载进配置文件类对象
pro.load(new InputStreamReader(stream));
//获取配置文件中所有的键值对信息
Set<Map.Entry<Object, Object>> set = pro.entrySet();
for (Map.Entry<Object, Object> entry : set)
{
resp.getWriter().write(entry.getKey() + ":" + entry.getValue()+"<br>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
doGet(req, resp);
}
}
dp.properties内容如下
userName=root
password=123456
结果如下