ServletContext

  • Post author:
  • Post category:其他




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


演示:

  • 首先创建一个类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。
image-20210824165337560

  • 首先获取到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 在为例,如下所示

image-20210824170148239

image-20210824171420404
>

资源根目录中的所有文件,经过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文件,如下所示

image-20210824172030775



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

结果如下

在这里插入图片描述