07-javax.servlet.ServletContext

时间:2021-08-05
本文章向大家介绍07-javax.servlet.ServletContext,主要包括07-javax.servlet.ServletContext使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

接着上面笔记中的ServletConfig接口中最后一个方法,

我们新建一个web项目c-ServletContext,

该项目中的两个Servlet实现类为AServlet和BServlet,

将init中的局部变量ServletConfig对象赋值给一个私有的成员变量config,

在各自的service方法中用该对象调用ServletConfig接口中的获取Servlet对象上下文的方法getServletContext分别在两个实现类中获取,并输出到浏览器。其他配置就不赘述了。

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">

    <servlet>
        <servlet-name>servletcontext1</servlet-name>
        <servlet-class>com.servlet.AServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletcontext1</servlet-name>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>servletcontext2</servlet-name>
        <servlet-class>com.servlet.BServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletcontext2</servlet-name>
        <url-pattern>/b</url-pattern>
    </servlet-mapping>
</web-app>

两个实现类中方法的代码如下

    private ServletConfig config = null;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.config = servletConfig;
    }

    @Override
    public ServletConfig getServletConfig() {
        return config;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        ServletConfig config = getServletConfig();
        ServletContext application = config.getServletContext();
        System.out.println(application);
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }

部署运行,在浏览器输入URL转到index页面,点击其中的两个连接分别输出两个Servlet对象中获取的ServletContext对象,可以看到运行窗口输出如下
两个Servlet对象输出的两个ServletContext对象内存地址相同,是同一个对象。并且该接口由Tomcat服务器实现,保存的地址是org.apache.catalina.core包下,实现类的类名是ApplicationContextFacade.java

结论:

--javax.servlet.ServetContext接口:
	1、Tomcat服务器完成对这个接口的实现
	完整的类名为:org.apache.catalina.core.ApplicationContextFacade
	javaweb程序员无需关心这个实现类,只需要面向ServetContext接口调用接口中的方法就行了。
	
	2、ServletContext具体是什么?什么时候被创建?什么时候被销毁?创建几个?
	--ServletContext翻译为:Servlet上下文
	--一个webapp只有一个web.xml文件,该文件在服务器启动时被解析
	--一个webapp只有一个ServletContext对象,该对象也是在服务器启动阶段被实例化
	--ServletContext对象在服务器关闭时被销毁
	--ServletContext对象对应的是web.xml文件,也可以说这个对象在项目运行时是web.xml文件的代表
	--ServletContext对象是所有Servlet对象周围环境的代表
	【在同一个webapp中所有Servlet对象共享一个环境,也就是共享同一个ServletContext对象】
	--当所有用户希望共享一个数据,可以将该数据存放到ServletContext对象中,
	但是放进ServletContext对象中的数据不建议涉及修改操作,因为该对象是多线程共享的,修改会有线程安全问题。
	
	3、ServletContext接口中常用的重点方法
	--Object getAttribute(String name)
	获取ServletContext范围中的数据,在底层该方法是调用了集合的get方法,Object value=map.get(key.value)
	--void removeAttribute(String name)
	移除ServletContext范围中的数据,在底层该方法是调用了集合的remove方法,map.remove(key)
	--void setAttribute(String name, Object object)
	向ServletContext范围中添加数据,在底层该方法是调用了集合的put方法,map.put(key,value)
	
	下面两个方法和ServletConfig接口中的一样,只不过获取web.xml文件中的信息是在<servlet></servlet>标签之外定义的上下文初始化参数标签<context-param>标签中的内容,具体xml文件代码如下面所示。
	--String getInitParameter(String name)
	--Enumeration getInitParameterNames()
	
	
	--String getRealPath(String path)
	该方法是获取文件的绝对路径,演示如下
	
	4、Servlet、ServletConfig和ServletContext之间的关系
	--一个Servlet对象对应一个ServletConfig对象
	--一个webapp中的所有Servlet对象共享一个ServletContext对象
	
	5、从测试将数据存储到ServletContext范围以及从中读取的操作中
	我们知道ServletContext范围可以跨用户传递,不同用户点击连接照样可以获取数据可以存储数据。
1、测试String getInitParameter(String name)和Enumeration getInitParameterNames()方法,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">

    <!--web.xml文件中配置上下文参数,该信息在服务器启动阶段解析xml文件时自动封装到ServletContext对象中-->
    <context-param>
        <param-name>username</param-name>
        <param-value>admin</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
    </context-param>

    <servlet>
        <servlet-name>servletcontext1</servlet-name>
        <servlet-class>com.servlet.AServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletcontext1</servlet-name>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>servletcontext2</servlet-name>
        <servlet-class>com.servlet.BServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletcontext2</servlet-name>
        <url-pattern>/b</url-pattern>
    </servlet-mapping>
</web-app>
service方法中的代码
  @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        ServletConfig config = getServletConfig();
        ServletContext application = config.getServletContext();
        //System.out.println(application);

        //ServletContext接口中获取所有上下文初始化参数的name的方法
        Enumeration<String> names = application.getAttributeNames();
        //遍历集合,并获取上下文初始化参数name对应的value
        while (names.hasMoreElements()){
            String name = names.nextElement();
            String value = application.getInitParameter(name);
            System.out.println(name+" = "+value);
        }
    }

结果如下

测试String getRealPath(String path)方法,获取文件绝对路径
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

        ServletConfig config = getServletConfig();
        ServletContext application = config.getServletContext();
        //System.out.println(application);

        //ServletContext接口中获取所有上下文初始化参数的name的方法
        Enumeration<String> names = application.getInitParameterNames();
        //遍历集合,并获取上下文初始化参数name对应的value
        while (names.hasMoreElements()){
            String name = names.nextElement();
            String value = application.getInitParameter(name);
            System.out.println(name+" = "+value);
        }

        //获取文件绝对路径方法
        //下面这样写必须webapp根路径(即WEB-INF目录上一级)下有该文件
        String absolutePath = application.getRealPath("/index.html");
    }

结果

测试void setAttribute(String name, Object object)和Object getAttribute(String name)方法,新建一个entity包,里面先新建一个实体用户类,代码如下
package com.entity;

public class User {

    private String usercode;

    private  String username;

    public String getUsercode() {
        return usercode;
    }

    public void setUsercode(String usercode) {
        this.usercode = usercode;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    

}
我们在AServlet类的service方法中用void setAttribute(String name, Object object)方法向ServletContext添加User对象中成员变量的数据。代码如下
        //创建User对象,并且给成员变量赋值
        User user = new User();
        user.setUsercode("12335");
        user.setUsername("高比例");
        
        //给ServletContext范围存储数据
        application.setAttribute("userObj",user);
我们在***BServlet***类的service方法中用Object getAttribute(String name)方法向ServletContext对象用name获取数据。

具体代码如下

        //ServletContext对象范围中读取数据
        Object value = application.getAttribute("usercode");
        servletResponse.getWriter().print(value);//向浏览器中输出数据
写好后部署项目运行,进入索引页,当我们点即测试AServlet后返回页面再点击测试BServlet,可以看到如下结果输出
先点击向ServletContext范围存储数据的资源的执行结果,再点击获取数据的资源类执行结果,可以得到如下输出结果
以上操作顺序相反,当先点击下面连接获取不到数据,因为还没有存,得到如下执行结果

原文地址:https://www.cnblogs.com/rjzhong/p/15106462.html