首页 > 其他分享 >ServletContext 的 4 个常见应用!

ServletContext 的 4 个常见应用!

时间:2025-01-19 12:10:15浏览次数:1  
标签:Web req 应用 resp 常见 ServletContext 子项目 转发

一、ServletContext类详解

Web容器在启动时,会为每一个Web项目创建一个对应的ServletContext对象。它是当前项目中所有Servlet实例之间信息交互的“中间商”。(参见“Servlet的运行原理”)

:一个Web项目对应一个ServletContext。(即:同一个Web项目中的所有servlet实例共用同一个ServletContext对象。)

二、常见应用

ServletContext的常见应用场景主要包括:

  • 数据共享:在一个Servlet中保存的数据,可以在另一个Servlet中使用。

  • 获取初始化参数

  • 请求转发

  • 读取资源文件

三、使用ServletContext实现:数据共享

(1)在上述父项目下再使用Maven模板新建一个MavenWeb子项目:servlet-02。

(2)同样地,为了避免以后出现兼容性问题,建议我们先将该子项目中的web.xml文件替换成“web-app_4_0”版本。

(3)同样地,在该子项目的main文件夹下新建一个java文件夹和一个resource文件夹,并将它们分别标记为“源码根目录”和“资源根目录”。

(4)编译父项目或子项目,此时父项目与子项目的目录结构如下图所示。

(5)配置Tomcat服务器,deploy(发布)servlet-02:war包,并为该子项目添加虚拟路径映射:/s2。

:如果只发布某一子项目,那么其它子项目的war包和虚拟路径映射可以删除。若不删除,则一起发布。

(6)在该子项目的java目录下新建一个com.atangbiji.servlet包,并在该包下新建一个Servlet1类,用于将数据以“键-值“对的形式保存在ServlContex对象中。同样地,让Servlet1类继承(extends)HttpServlet类,以实现Servlet接口。然后,在Servlet1类中重写doGet和doPost方法。

Servlet1.java文件:

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();//获取ServlContex对象
        String usernameVal = "阿汤笔迹";
        servletContext.setAttribute("username",usernameVal);//将数据以“键-值“对的形式保存在ServlContex对象中
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);    //因为`get`和`post`只是不同的Http请求方式,所以它们之间可以相互调用。
    }
}

(7)同样地,com.atangbiji.servlet包下再新建一个Servlet2类,用于获取ServlContex对象中保存的“键-值“对。

Servlet2.java文件:

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();//获取ServlContex对象
        String usernameVal = (String)servletContext.getAttribute("username");//从ServletContext中获取username的值

        resp.setHeader("Content-Type", "text/html; charset=utf-8");
        resp.getWriter().print("Servlet2从ServletContext中获取到username的值为:" + usernameVal);//在页面上输出响应
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);    //因为`get`和`post`只是不同的Http请求方式,所以它们之间可以相互调用。
    }
}

(8)同样地,在该子项目的Web配置文件(web.xml)中注册(映射)我们自己编写的两个Servlet,并为它们分别提供一个浏览器可以访问的路径。

web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <servlet>
        <servlet-name>SetServletContext</servlet-name>
        <servlet-class>com.atangbiji.servlet.Servlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SetServletContext</servlet-name>
        <url-pattern>/setVal</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>GetServletContext</servlet-name>
        <servlet-class>com.atangbiji.servlet.Servlet2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetServletContext</servlet-name>
        <url-pattern>/getVal</url-pattern>
    </servlet-mapping>

</web-app>

(9)在IDEA中启动Tomcat。在浏览器中先输入http://localhost:8080/s2/setVal加载Servlet1,然后再输入http://localhost:8080/s2/getVal,访问结果如下:

:我们可以通过IDEA为我们提供的Web窗口来查看Web项目的结构。

四、使用ServletContext实现:获取初始化参数

(1)在Web.xml文件中配置Web应用的初始化参数(如:连接mybatis的url)。

Web.xml文件:

<!--  配置Web应用初始化参数(连接mybatis的url) -->
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>

(2)在该子项目com.atangbiji.servlet包下新建一个Servlet3类,用于获取Web应用的初始化参数。同样地,让Servlet3类继承HttpServlet类,以实现Servlet接口。然后,在Servlet3类中重写doGet和doPost方法。

Servlet3.java文件:

public class Servlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();//获取ServlContex对象

        String url = servletContext.getInitParameter("url");//获取连接mybatis的url
        resp.getWriter().print(url);//在页面上输出响应
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);    //因为`get`和`post`只是不同的Http请求方式,所以它们之间可以相互调用。
    }
}

(3)同样地,在该子项目的Web配置文件(web.xml)中注册(映射)我们自己编写的Servlet,并为它提供一个浏览器可以访问的路径。

web.xml文件:

<servlet>
  <servlet-name>GetInitParameter</servlet-name>
  <servlet-class>com.atangbiji.servlet.Servlet3</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>GetInitParameter</servlet-name>
  <url-pattern>/getInitParameter</url-pattern>
</servlet-mapping>

(4)在IDEA中启动Tomcat。在浏览器中输入http://localhost:8080/s2/getInitParameter,访问结果如下:

五、使用ServletContext实现:请求转发

5.1 什么是请求转发

请求转发(RequestDispatcher)指的是:一个web资源(Servlet1)接受到客户端的请求后,通知服务器去调用另外一个web资源(Servlet2)进行处理。

5.2 请求转发的工作原理

在 Servlet中,通常使用 forward()方法将当前请求转发给其他的Web 资源进行处理。请求转发的工作原理如下图所示:

5.3 请求转发的特点

  • 请求转发是服务器端的行为,浏览器不知道在服务器内部发生了转发行为,更无法得知转发的次数。

  • 请求转发之后,浏览器地址栏中的 URL 不会发生变化。

  • 请求转发不支持跨域访问,只能跳转到当前应用中的资源。

  • 参与请求转发的 Web资源之间共享同一 request对象和 response对象。

  • 只有转发到最后一个Web资源时,生成的响应才会被发送到客户端。

5.4 请求转发的实现

(1)在该子项目com.atangbiji.servlet包下新建一个Servlet4类,用于将访问Servlet4的请求转发到Servlet3的请求路径上来。同样地,让Servlet4类继承HttpServlet类,以实现Servlet接口。然后,在Servlet4类中重写doGet和doPost方法。

Servlet4.java文件:

public class Servlet4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();//获取ServlContex对象
        //获取访问该Servlet的请求将要转发的路径
        RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/getInitParameter");
        //调用forward方法实现请求转发
        requestDispatcher.forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);    //因为`get`和`post`只是不同的Http请求方式,所以它们之间可以相互调用。
    }
}

(2)同样地,在该子项目的Web配置文件(web.xml)中注册(映射)我们自己编写的Servlet,并为它提供一个浏览器可以访问的路径。

web.xml文件:

<servlet>
  <servlet-name>RequestDispatcher</servlet-name>
  <servlet-class>com.atangbiji.servlet.Servlet4</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>RequestDispatcher</servlet-name>
  <url-pattern>/requestDispatcher</url-pattern>
</servlet-mapping>

(3)在IDEA中启动Tomcat。在浏览器中输入http://localhost:8080/s2/requestDispatcher,此时服务器会将我们的请求转发到/getInitParameter路径上来。访问结果如下:

:请注意请求转发与请求重定向的区别,我们将在介绍重定向是对比说明。

六、ServletContext应用示例:读取资源文件

(1)在该子项目的resources文件夹下新建一个db.properties文件。

db.properties文件:

username = root
password = 123456789

(2)在该子项目com.atangbiji.servlet包下新建一个propertiesServlet类,用于读取db.properties资源文件。同样地,让propertiesServlet类继承HttpServlet类,以实现Servlet接口。然后,在propertiesServlet类中重写doGet和doPost方法。

propertiesServlet.java文件:

public class propertiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();//获取ServlContex对象
        //以数据流的方式获取资源
        InputStream stream = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");//项目打包后的相对路径

        Properties prop = new Properties();
        //加载数据流
        prop.load(stream);
        //获取属性值
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        //在页面上输出响应
        resp.getWriter().print(username + ":" + password);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);    //因为`get`和`post`只是不同的Http请求方式,所以它们之间可以相互调用。
    }
}

(3)同样地,在该子项目的Web配置文件(web.xml)中注册(映射)我们自己编写的Servlet,并为它提供一个浏览器可以访问的路径。

web.xml文件:

<servlet>
    <servlet-name>PropertiesServlet</servlet-name>
    <servlet-class>com.atangbiji.servlet.propertiesServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>PropertiesServlet</servlet-name>
    <url-pattern>/propertiesServlet</url-pattern>
</servlet-mapping>

(4)在IDEA中启动Tomcat。在浏览器中输入http://localhost:8080/s2/propertiesServlet,访问结果如下:

:由于Maven的“约定大于配置”思想,我们以后可能会遇到我们自己写的配置文件(如:我们配置文件*.xml写在了项目中的Java目录下)无法被导出或者无法生效的问题。该问题的解决方法是:在pom.xml的<build>……</build>中配置resources,修改Maven约定的过滤条件,来防止我们的资源导出失败。

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
  <resources>
    <!--选择需要导出资源的路径,可以选择多个-->
    <resource>
      <directory>src/main/resources</directory>
      <!--写入需要导出的什么类型的文件-->
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <!--不去过滤这些文件-->
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <!--不去过滤这些文件-->
      <filtering>false</filtering>
    </resource>
  </resources>
</build>

关注 “阿汤笔迹” 微信公众号

标签:Web,req,应用,resp,常见,ServletContext,子项目,转发
From: https://www.cnblogs.com/o-O-oO/p/18679470

相关文章

  • 如何在仿真分析,预测中 应用风力发电、光伏发电数据、用电负荷数据集,构建一个全面的时
    风力发电、光伏发电数据、用电负荷数据集,用于仿真分析,预测等。[1]光伏数据,光伏出力年光伏数据集,包含光伏发电功率、多种类型光照辐射强度数据(DNI,DHI,GHI),附带多种数据,可用于光伏场景生成与缩减、光伏特性分析、光伏优化调度等。[2]光伏预测功率数据2007-2020光伏预测功......
  • 【pywinauto 库】启动PC端应用程序 - 上篇
    一、简介经过上一篇的学习、介绍和了解,想必小伙伴或者童鞋们,已经见识到pywinauto的强大了,今天继续介绍pywinauto,上一篇已经可以打开计算器了,这里宏哥再提供其他方法进行打开计算器和非电脑自带程序。pywinauto可以启动电脑自带的应用程序,也可以启动电脑安装的应用程序。二、运......
  • 第10篇:从入门到精通:深入理解Python继承与多态的概念及应用
    第10篇:继承与多态内容简介本篇文章将深入探讨Python中的继承与多态概念。您将学习如何通过类的继承实现代码的重用,掌握方法重写的技巧,了解如何使用super()函数调用父类的方法,并探索多态的实现与应用。通过丰富的代码示例,您将能够熟练运用继承与多态,提升您的面向对象编程(OO......
  • Java 大视界 -- Java 大数据中的图神经网络应用与实践(53)
           ......
  • 利用坦克PWA3快速为应用配置域名:以Gogs为例
    全文概述本文介绍了如何利用坦克PWA3平台快速为Gogs应用配置域名的过程。随着互联网技术的发展,自托管Git服务变得越来越受欢迎,其中Gogs凭借其轻量级和易于安装的特点受到众多开发者的青睐。为提高用户体验,为应用配置一个易记且专业的域名至关重要。文中详细阐述了在坦克PWA3平台......
  • LRU算法的应用
    13.LRU算法的应用题目关于用户信息的需求假定在一个复杂的系统中,需要抽象出一个用户系统,提供给其他子系统使用,该如何实现。子系统对用户信息的查询频率很高,要注意性能问题。用户信息是存储在数据库里的,但是对于查询频率高的数据,不能每一次请求时都去查询数据库。思路哈希表......
  • 运算放大器应用电路设计笔记(四)
    动态范围表示正常工作时最小振幅与最大振幅的范围。例如,最小振幅为-14v,最大振幅为+14v,则动态范围为±14v,也有用绝对值或有效值表示振幅,最大电压与最小电压之比为动态范围,也称为多少dB。这时,最大振幅由电源电压决定,最小振幅由噪声或失调电压决定。确保动态范围的最简单方法......
  • 极坐标与直角坐标之间变换的原理和应用示例
            极坐标变换的原理是将平面上的点从直角坐标系转换为极坐标系,或者从极坐标系转换为直角坐标系。以下是关于极坐标变换原理的详细解释:一、极坐标系的基本概念        在极坐标系中,一个点的位置由两个参数确定:径向距离(ρ)和极角(θ)。        (1)......
  • 在 nuget 私服 BaGet 中应用https 以及 gitea action runner 自动打包
    最近赋闲,想起之前工作中代码管理的一点经历,就是在打包项目的时候,类库的版本号几乎没变过,一个项目运行多少年了,版本号还是1.0.0。......
  • manage-bde 是一个用于管理 BitLocker 驱动器加密的命令行工具,广泛应用于 Windows 操
    manage-bde|MicrosoftLearn manage-bde命令按功能进行分类,并以表格形式呈现的结果:功能分类命令描述基本命令manage-bde启动 manage-bde 命令行工具,显示相关帮助信息。查看加密状态manage-bdestatus显示所有驱动器的BitLocker加密状态,包括是否启用、......