ServletContext详解

1.首先我们在IDEA里面新建一个工程: 

 我们进行创建之后如下,我们点击父工程pom.xml,发现多了一个moudle:

 我们将Servlet-02里面的pom.xml进行必要的清除,设置一个干净的项目:

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

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>untitled2</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>servlet-02</artifactId>
    <packaging>war</packaging>


</project>

我们将该删的进行删除,即可发现一个干净的项目。

如果这个过程中出现错误,我们点击刷新即可。

对于我们要进行修改的web.xml,修改这个比较麻烦。

 对于经常共用的东西,我们可以在外面设置一个东西: (note.md)

 我们的公用的代码如下所示:

web.xml
```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_3_1.xsd"
version="3.1"
metadata-complete="true">

</web-app>
```

这里面的点为esc键下面的键盘,···。

之后我们将main项目进行补全:

我们之后进行建包,同时建立HelloServlet类,然后进行在类里面编辑方法。

 写完Servlet之后,立马进入web,xml里面进行注册:

 <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.rgf.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

这样子正常的操作就完成了。

之后我们进行查看Tomcat,我们点击如下所示:

 进入之后,我们选择我们所创建的包servlet-02,将此前的包进行删除,确保里面只有一个,这样子可以快速打包,避免一次打多个包:

 我们点击运行之后如下所示:

 我们出现这个画面即为成功。

由于我们没有写输出,所以这个为空白页面。

我们从HttpServlet,按住ctrl,点击鼠标左键,进入HttpServlet的源码界面,我们来进行分析:

 我们依靠这三个方面来进行分析:主要通过Structure分析方法:

 我们了解如下所示:

//this.getInitParameter()  初始化参数
        //this.getServletConfig()  Servlet配置
        //this.getServletContext() Servlet上下文
       // this指代自己,因为继承了HttpServlet所有父类的方法,就能使用父类方法this.。

在web.xml了解如下所示:

 <!-- <context-param>获取全局的参数-->
        <!--<param-name></param-name>-->
       <!--<param-value></param-value>-->
    <!-- </context-param>-->
     <servlet>
         <servlet-name>hello</servlet-name>
         <servlet-class>com.rgf.servlet.HelloServlet</servlet-class>
         <!--init-param>给HelloServlet放置一些初始的参数,这些参数都没有什么用-->
          <!--<param-name></param-name>-->
          <!--<param-value></param-value>-->
     <!--</init-param>-->

 我们进行重点了解ServletContext,如下所示:

比如我们在淘宝登录的时候,登陆完之后的注册信息会带到很多页面,跳到其他页面也是登录上去的,这个不是自己做到的,是中间商做到的。

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。

这个网站就是由这个对象来进行管理的:ServletContext

应用:1.共享数据

我在这个Servlet保存的数据可以在另外一个Servlet中拿到:

 但是这种方法是比较不合适的。

如下所示:

 我们利用ServletContext进行检验:

我们新建一个class,类名为GetServlet:(读取的类)

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后,我们将HelloServlet进行修改:(放置的类)

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后,我们新建了一个Servlet之后,我们在web.xml进行新建一个servlet:

 <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.rgf.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

点击运行之后,我们出现如下所示:

 我们看到了null,之后我们进行完善:代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //数据放上面
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
        //响应放下面
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("rgf"+username);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

我们在设置过程中我们可以看其他网页的设置进行设置:

 之后我们重新启动后如下所示:

 我们利用hello里面的set方法先要赋值,getc里面的get才能取到值,我们示例如下:

我们先存起来如下所示:

 之后我们取出来如下所示:

我们打开这个GetServlet进入该类:在ServletContext,按住ctrl键,点击鼠标左键,进入源代码:

 进入源代码之后,我们点击structure,查看结构:

我们查看源代码,进行对源代码的分析如下所示:

源码分析:

里面的@Deprecated,该标签标记为已过时被废弃的或者不建议被使用:

 获得自己的路径:

String getContextPath();

获得版本信息:

int getMajorVersion();

    int getMinorVersion();

    int getEffectiveMajorVersion();

    int getEffectiveMinorVersion();

获得自己这个对象:(可以通过某一个字符串进行获取)

ServletContext getContext(String var1);

获取复杂的消息类型:

String getMimeType(String var1);

获取资源的路径:

Set<String> getResourcePaths(String var1);

获取资源把它变成一个流:

 InputStream getResourceAsStream(String var1);

获取一个RequestDispatcherr,通过请求转发:

  RequestDispatcher getRequestDispatcher(String var1);

获取一个RequestDispatcher,通过名字转发:

 RequestDispatcher getNamedDispatcher(String var1);

获得真实的地址:

String getRealPath(String var1);

获得服务的信息:

String getServerInfo();

获得初始化的参数:

 String getInitParameter(String var1);

进行设置:(上面为获得,下面就是设置了)

void setAttribute(String var1, Object var2);

3.我们可以设置新的一个类:ServletDemo03:

在里面进行写如下代码:

context.getInitParameter("");

这个除了可以获取setInitParameter("");还可以获取如下所示:

我们可以在web.xml里面进行配置:

   <!-- <context-param>获取全局的参数--> 
<!--配置一些web应用的初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> //jdbc的连接url
    </context-param>

web.xml里面的初始化参数我们可以在ServletDemo03里面拿到:

我们的ServletDemo03里面的代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();


        String url = context.getInitParameter("url");
        
        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在web.xml里面进行注册该类的信息:

<servlet>
        <servlet-name>gp</servlet-name>
        <servlet-class>com.rgf.servlet.ServletDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>gp</servlet-name>
        <url-pattern>/gp</url-pattern>
    </servlet-mapping>

综上所述,所以ServletContext除了数据共享还可以获取初始化参数:

2.获取初始化参数

(1)ServletDemo03代码编写:

package com.rgf.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();


        String url = context.getInitParameter("url");

        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

(2)web.xml代码进行设置:

 <servlet>
        <servlet-name>gp</servlet-name>
        <servlet-class>com.rgf.servlet.ServletDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>gp</servlet-name>
        <url-pattern>/gp</url-pattern>
    </servlet-mapping>

我们进行运行之后如下所示:

3.请求转发(RequestDispatcherr)

我们设置一个新的类:ServletDemo04,我们编写该类的时候,会发现RequestDispatcher,我们进入该类的源码进行查看:

public interface RequestDispatcher {
    String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
    String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
    String FORWARD_MAPPING = "javax.servlet.forward.mapping";
    String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
    String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
    String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
    String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
    String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
    String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
    String INCLUDE_MAPPING = "javax.servlet.include.mapping";
    String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
    String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
    String ERROR_EXCEPTION = "javax.servlet.error.exception";
    String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
    String ERROR_MESSAGE = "javax.servlet.error.message";
    String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
    String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
    String ERROR_STATUS_CODE = "javax.servlet.error.status_code";

    void forward(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    void include(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
}

我们发现该类的源码里面:只有forward和include两个方法,其他的都是一堆常量。

我们在ServletDemo04里面进行编写的代码如下所示:

package com.rgf.servlet;

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;
import java.io.IOException;

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //数据放上面
        ServletContext context = this.getServletContext();
        System.out.println("进入了ServletDemo04");
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
        //我们上面只有请求路径,还没有转发
        requestDispatcher.forward(req,resp); //调用forward方法实现请求转发
        //需要传两个参数,就是从HttpServletRequest的rep请求处理,到HttpServletResponse的resp请求响应回去


        String url = context.getInitParameter("url");

        //响应放下面
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在web.xml里面的代码如下所示:

<servlet>
        <servlet-name>sd4</servlet-name>
        <servlet-class>com.rgf.servlet.ServletDemo04</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd4</servlet-name>
        <url-pattern>/sd4</url-pattern>
    </servlet-mapping>

 进行运行之后如下所示:

 我们可以看到,jdbc:mysql://localhost:3306/mybatis,本是http://localhost:9571/servlet_02_war/gp里面的,但是http://localhost:9571/servlet_02_war/sd4加载的也是这个页面里面的内容。

 我们可知Status Code里面为200,而不是重定向的300,这是转发实现的。

我们请求到web.xml里面的<servlet-name>sd4</servlet-name>,通过一个getRequestDispatcher转发到了另外一个页面,转发的时候路径不会发生变化。之后的重定向路径是会发生变化的。

 4.读取资源文件

Properties,这里需要用到这个,我们去那个类里面进行new一个对象。

我们在ServletDemo03里面进行编写如下代码:

  Properties properties = new Properties();

我们进入Properties类里面查看源码,如下所示:

Properties里面继承了一些东西,它里面有一些自己的方法。

 我们对这些方法进行分析:

(1)可以传递一个自定义参数,让他读取某一个,否则就是默认的

public Properties(Properties defaults) {

(2) 设置一些属性的值,就是put里面的return put(key, value);

public synchronized Object setProperty(String key, String value) {

(3)加载,可以加载一个字符流也可以加载字节流

return put(key, value);

(4)往磁盘写。

 public void store(Writer writer, String comments)

(5)从XML里面去加载

public synchronized void loadFromXML(InputStream in)

(6)get一个属性

public String getProperty(String key) {

我们创建一个properties文件,可以在任何地方创建,只要没有超出main。

我们在resources里面进行创建:

 我们在里面输入如下所示:

 我们进行了解我们在初学properties是如何进行读取的。

我们进行创建该类如下所示:

 我们一般都采用流,即为load(inStream);我们直接读取db.properties的绝对地址即可。但是现在是web应用,没有办法去保证绝对地址,因为web服务要走服务器,我们需要去web里面去拿,所以我们要观察db.properties会生成在web里面的哪个地方。

首先我们通过Maven,clean一下:

出现如下所示即可完成:

  之后我们重新点击运行,进行测试:

 我们发现在WEB-INF里面的classes类里面,com下面有db.properties。

classpath叫类路径。里面还有servlet文件。

我们进行做如下测试:

我们可以将 db.properties复制到main下面的文件命名为aa.properties,重新运行之后,看target里面是否有aa.properties。

我们重新运行之后如下所示:

 我们发现里面没有aa.properties。

在Maven里面资源导出可能存在问题,Maven由于它的约定大于配置,我们之后可能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案如下所示:在build下面加个resouces.我们将该代码放到当前项目的pom.xml里面:

 <!--假如在build中配置resources,来防止我们资源导出失败的问题-->
<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

我们将该代码添加之后,重新运行之后,结果如下所示:

我们发现里面成功的出现了aa.properties。如果没有出现的话,我们可以再通过Maven里面的clean进行清除,然后再重新运行。即可进行查询。

Properties

在java目录下新建Properties

在resouces目录下新建Properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath;

我们了解到路径是怎么放的了,我们现在可以去读他了。

我们创建一个类为ServletDemo05,我们编写的代码如下所示:

package com.rgf.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        //把资源变成一个流
//第一个/不能省略,代表当前web项目,不然无法找到,这是一个相对定位的感觉
        Properties prop = new Properties();
        prop.load(is); //文件的流就拿到了。
        String user = prop.getProperty("username");//最好直接从db.properties文件里面直接复制。
        String pwd = prop.getProperty("password");

        resp.getWriter().print(user+":"+pwd);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

之后我们在那个web.xml里面进行配置如下所示:

 <servlet>
        <servlet-name>sd5</servlet-name>
        <servlet-class>com.rgf.servlet.ServletDemo05</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd5</servlet-name>
        <url-pattern>/sd5</url-pattern>
    </servlet-mapping>

之后我们运行进行测试:

 我们可以读取到resouces里面的db.properties。我们是否可以读取到我们在main下面的aa.properties。我们进行测试如下所示:

我们的aa.properties文件如下所示:

 我们运行之后的界面如下所示:

 我们可知我们可以进行读取到。

综上所述:我们的读取资源文件的思路如下所示:

需要一个文件流,只要能变成一个流,我们即可进行读取到。

Properties(文件内容为:)

username=root
password=123456

通过ServletContext读取配置文件。

ServletContext是一个对象,我们之后还会再学习一些对象,比如Response,Request,Cookie,Session这些对象,我们就是再学习一个一个的类,这个类有哪些方法,如何去使用等等。针对ServletContext的四个应用。我们会在后面通过Session或者Request的一些方法来取代Context的共享数据的作用,我们更多的是用Session或者Request的一些方法来实现共享数据。第二个获取初始化参数我们基本不使用这个。第三个请求转发我们使用Request。第四个读取资源文件的话我们更多的是用类加载器。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直再追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值