深度好文之Servlet技术详解(六)ServletContext对象&ServletConfig对象

目录

一.ServletContext对象介绍

二.ServletContext对象的使用

1.相对路径转绝对路径

2.获取容器的附加信息

 3.获取web.xml文件中的信息 

4.全局容器

三.ServletContext对象生命周期

四.ServletConfig对象


一.ServletContext对象介绍

ServletContext 官方叫 Servlet 上下文。服务器(eg:Tomcat)会为每一个 Web 应用创建一个 ServletContext 对象。这个对象全局唯一,而且 Web 应用 中的所有 Servlet 都共享这个对象。所以叫全局应用程序共享对象。
ServletContext 对象的作用
  • 相对路径转绝对路径
  • 获取容器的附加信息
  • 读取配置信息
  • 全局容器

二.ServletContext对象的使用

1.相对路径转绝对路径

context.getRealPath("path")
该方法可以将一个相对路径转换为绝对路径,在文件上传与下载时,需要用到该方法做路径的转换。

静态资源应该放到web目录下或 web子目录下,相对路径是指相对于项目的根目录而言的,比如本节在web下创建image,将heat.jpg放到image下,则此时heat.jpg的相对路径是

"image/heat.jpg"

 之前已经讲过将项目自动部署到Tomcat的webapps目录下了,这里又新增了image文件夹,部署后如果发现webapps中的项目目录下仍没有image,则将项目目录散删除,然后冲重新部署。

如果不删除,我遇到了如下错误:

以上篇文章的文件下载案例进行稍加改造,

FileDownServlet.java:
package com.first.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.*;

public class FileDownServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

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

        //获取ServletContext对象
        ServletContext servletContext=this.getServletContext();
        //路径转换
        String realPath=servletContext.getRealPath("image/heat.jpg");
        System.out.println("绝对路径:"+realPath);
        //读取下载文件
        File file=new File(realPath);
        //用字节输入流将文件读入
        InputStream is=new FileInputStream(file);
        /*
        is.available()返回is的大小,因为一般大太大的东西一次性读入就行,
        大的话可以设置一次读1024B,2048B等
         */
        //缓冲区
        byte[] buff =new byte[is.available()];
        //将文件读入buff中
        is.read(buff);

        //在响应中添加附加信息
        resp.addHeader("Content-Disposition", "attachment; filename="
                +new String(file.getName().getBytes("gbk"),"iso-8859-1"));
        //产生响应
        //字节输出流
        OutputStream os=resp.getOutputStream();
        os.write(buff);
        os.flush();
        os.close();
    }
}

输出:

控制台输出绝对路径:

绝对路径:D:\Tomcat\apache-tomcat-9.0.34\webapps\ajaxDemo\image\heat.jpg

2.获取容器的附加信息

servletContext.getServerInfo()
返回 Servlet 容器的名称和版本号
servletContext.getMajorVersion()
返回 Servlet 容器所支持 Servlet 的主版本号。
servletContext.getMinorVersion()
返回 Servlet 容器所支持 Servlet 的副版本号。
GetBaseInfoServlet.java:
package com.first.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;
import java.io.PrintWriter;

public class GetBaseInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext=this.getServletContext();
        //获取容器信息
        String servletInfo=servletContext.getServerInfo();
        //获取容器支持Servlet的主版本号
        int majorVersion=servletContext.getMajorVersion();
        //获取容器支持Servlet的副版本号
        int minorVersion=servletContext.getMinorVersion();

        //设置响应编码,消除浏览器显示中文乱码
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        pw.println("容器基本信息:"+servletInfo);
        pw.println("容器支持Servlet的版本号:"+majorVersion+"."+minorVersion);
        pw.flush();
        pw.close();
    }
}
web.xml配置:
    <servlet>
        <servlet-name>GetBaseInfoServlet</servlet-name>
        <servlet-class>com.first.servlet.GetBaseInfoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetBaseInfoServlet</servlet-name>
        <url-pattern>/getBaseInfo.do</url-pattern>
    </servlet-mapping>

输出:

容器基本信息:Apache Tomcat/9.0.34
容器支持Servlet的版本号:4.0

 3.获取web.xml文件中的信息 

servletContext.getInitParameter("key")
该方法可以读取 web.xml 文件中标签中的配置信息。
servletContext.getInitParameterNames()
该方法可以读取 web.xml 文件中所有 param-name 标签中的值。

配置web.xml中的键值对:

注意键值对的位置,要放在最上面

 ContextReadInfoServlet.java:

package com.first.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;
import java.io.PrintWriter;
import java.util.Enumeration;

public class ContextReadInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext=this.getServletContext();
        //获取所有的<param-name>的值
        Enumeration<String> initParameterNames=servletContext.getInitParameterNames();

        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        while(initParameterNames.hasMoreElements()){
            String name=initParameterNames.nextElement();
            String value=servletContext.getInitParameter(name);
            pw.println("Name:"+name+" = Value:"+value);
        }
        pw.flush();
        pw.close();
    }
}

在web.xml中配置servlet:

    <servlet>
        <servlet-name>ContextReadInfoServlet</servlet-name>
        <servlet-class>com.first.servlet.ContextReadInfoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ContextReadInfoServlet</servlet-name>
        <url-pattern>/readInfo.do</url-pattern>
    </servlet-mapping>

输出:

Name:key1 = Value:未来
Name:key2 = Value:怎么样

4.全局容器

servletContext.setAttribute("key",ObjectValue)
向全局容器中存放数据。
servletContext.getAttribute("key")
从全局容器中获取数据。
servletContext.removeAttribute("key")
根据 key 删除全局容器中的 value

可以把servletContext看做是全局容器对象。

当servlet被实例化以后,tomcat会立即调用一次init来完成一些初始化的动作。所以我们可以在init中向全局容器添加一些信息 。

GlobalContainerServlet.java:
package com.first.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;
import java.io.PrintWriter;

public class GlobalContainerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext =this.getServletContext();
        //从全局容器中获取数据
        String value1= (String) servletContext.getAttribute("key1");
        String value2= (String) servletContext.getAttribute("key2");

        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        pw.println(value1);
        pw.println(value2);
        pw.flush();
        pw.close();
    }

    @Override
    public void init() throws ServletException {
        //获取ServletContext对象
        ServletContext servletContext =this.getServletContext();
        //向全局容器中存放数据
        servletContext.setAttribute("key1","一片舟");
        servletContext.setAttribute("key2","流浪");
    }
}

配置web.xml:

    <servlet>
        <servlet-name>GlobalContainerServlet</servlet-name>
        <servlet-class>com.first.servlet.GlobalContainerServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GlobalContainerServlet</servlet-name>
        <url-pattern>/global.do</url-pattern>
    </servlet-mapping>

输出:

体现全局性,这个项目的其他servlet也可以访问全局容器

访问http://localhost:8888/ajaxDemo/global.do

再把从全局容器中获取数据的代码复制到其他servlet试试,如下

 访问http://localhost:8888/ajaxDemo/readInfo.do

三.ServletContext对象生命周期

当容器启动时会创建 ServletContext 对象并一直缓存该对象,直到容器关闭后该对象生命周期结束。 ServletContext 对象的生命周期 非常长,所以在使用全局容器时不建议存放业务数据(而是放到数据库当中)。 一般在全局容器放置一些永远不变的配置信息。

四.ServletConfig对象

ServletConfig 对象对应 web.xml 文件中的节点。当 Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息,封装到一个 ServletConfig 对象中。我们可以通过该对象读取节点中的配置信息。
servletConfig.getInitParameter("key")
该方法可以读取 web.xml文件中 <servlet> 标签中 <init-param> 标签中的配置信息。
servletConfig.getInitParameterNames()
该方法可以读取 web.xml文件中当前 <servlet> 标签中所有 <init-param> 标签中的值。
使用上面两个函数时只能在当前servlet中去读取配置信息,因为一个servlet对象对应一个ServletConfig对象,这也是和ServletContext读取web.xml配置信息的区别之一。

配置web.xml:

    <servlet>
        <servlet-name>GetConfigServlet</servlet-name>
        <servlet-class>com.first.servlet.GetConfigServlet</servlet-class>
        <init-param>
            <param-name>key1</param-name>
            <param-value>嘻嘻</param-value>
        </init-param>
        <init-param>
            <param-name>key2</param-name>
            <param-value>吼吼</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetConfigServlet</servlet-name>
        <url-pattern>/config.do</url-pattern>
    </servlet-mapping>
GetConfigServlet.java:
package com.first.servlet;

import javax.servlet.ServletConfig;
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;
import java.io.PrintWriter;
import java.util.Enumeration;

public class GetConfigServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取ServletContext对象
        ServletConfig servletConfig=this.getServletConfig();

        //读取web.xml文件中当前<servlet>标签中所有<init-param> 标签中的值,即key
        Enumeration<String> initParameterNames=servletConfig.getInitParameterNames();
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        while (initParameterNames.hasMoreElements()){
            String name=initParameterNames.nextElement();
            //根据key得到value
            String value=servletConfig.getInitParameter(name);
            pw.println("name:"+name+"value:"+value);
        }
        pw.flush();
        pw.close();
    }
}

输出:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深海鱼肝油ya

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

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

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

打赏作者

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

抵扣说明:

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

余额充值