ServletContext对象

1. 概念:代表整个web应用,可以和程序的容器(服务器)来通信

特点:

  1. 产生:部署了Web的服务器一启动,ServletContext对象就会创建,服务器不关闭,就会一直存在。
  2. 销毁:关闭服务器或者是从web服务器上卸载该程序的时候,该对象销毁。

功能:ServletContext对象保存着 所有用户所有请求的数据,所以可以从当前启动的Web服务器项目中Servlet类中拿去任何用户的请求数据。

2. 获取

  1. 通过request对象获取
    request.getServletContext();
  2. 通过HttpServlet获取
    this.getServletContext();

为什么可以通过this来调用getServletContext方法获取ServletContext对象

  1. GenericServlet抽象类实现了Servlet
  2. HttpServlet继承了GenericServlet
  3. 一个类要想成为Servlet类要先继承HttpServlet或者实现servlet类。
  4. GenericServlet抽象类中有getServletContext方法,方法体如下图:
  5. 总结:HttpServlet继承了GenericServlet,servlet实现类又继承了HttpServlet,所以继承了方法,所以可以直接通过this来调用。

3. 功能

1. 获取MIME类型:

1.1 MIME类型的具体用途:

  • 当我们打开一个照片的时候,我们要用照片相对应的打开器打开
  • 我我们打开一个视频的时候,我们要用视频相对应的播放器打开

总结:所以MIME类型就是在服务端发数据到客户端(前端页面)的时候,告诉客户端,我发给你的数据是什么格式的,你需要用该格式相对应的应用打开。

1.2 MIME类型的简单介绍和获取:

  1. MIME类型:在互联网通信过程中定义的一种文件数据类型
  • 格式: 大类型/小类型 text/html image/jpeg
  1. 获取:String getMimeType(String file)

2. 域对象:共享数据

  1. setAttribute(String name,Object value)
  2. getAttribute(String name)
  3. removeAttribute(String name)
  • ServletContext对象范围:所有用户所有请求的数据

3. 获取文件的真实(服务器)路径

  • 方法:String getRealPath(String path)
    各种路径下的访问资源
String b = context.getRealPath("/b.txt");//web目录下资源访问
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问

客户端请求资源,是向服务器上部署的Web项目发送的请求

  • IDEA中开发的Web项目,部署到Tomcat服务器然后发布,
  • 在IDEA工作目录下会有一个Web项目,部署到Tomcat服务器上后,
  • Tomcat服务器也会有一个相同的Web项目,
  • 所以客户端(前端页面)请求后端资源(servlet资源)的时候,请求的是Tomcat服务器上部署的项目

怎样查找Web项目部署的真实路径?(以Tomcat服务器为例)

  • 在Tomcat服务器启动后,在server菜单栏下,有一个Using CATALINA_BASE
  • Using CATALINA_BASE后的路径中有一个conf配置目录,conf目录下有个Catalina目录
  • Catalina目录中可以找到一个.XML的文件,打开文件找到docBase属性,docBase的属性值就是Web项目部署的真实路径。
  • 在Web部署的真实路径下会有一个WEB-INF目录,WEB-INF目录下的classes目录中存放着所有的java类资源,也就是src下的资源。

java context 的利弊 java的context对象_服务器


java context 的利弊 java的context对象_服务器_02

4.案例

文件下载需求:

  1. 页面显示超链接
  2. 点击超链接后弹出下载提示框
  3. 完成图片文件下载

分析:

  1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
  2. 任何资源都必须弹出下载提示框
  3. 使用响应头设置资源的打开方式:
  • content-disposition:attachment;filename=文件名.xxx

步骤:

  1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
  2. 定义Servlet
  3. 获取文件名称
  4. 使用字节输入流加载文件进内存
  5. 指定response的响应头: content-disposition:attachment;filename=xxx
  6. 将数据写出到response输出流

问题:

  • 中文文件问题
    * 解决思路:
  1. 获取客户端使用的浏览器版本信息
  2. 根据不同的版本信息,设置filename的编码方式不同

代码演示:

前端代码:

java context 的利弊 java的context对象_服务器_03

后端代码:

@WebServlet("/downServlet")
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获取filename属性的属性值
        String filename = request.getParameter("filename");
        //获取servletContext对象
        ServletContext servletContext = this.getServletContext();
        //获取Tomcat服务器中部署的Web项目下img目录中的文件真实路径。
        String realPath = servletContext.getRealPath("/img/"+filename);
        //获取字符输入流,将真实文件路径作为参数传入,写入到内存。
        FileInputStream fileInputStream = new FileInputStream(realPath);
		//通过getParameter获取属性值,值有后缀名,传入得到的属性值,根据后缀得到mimeType类型
        String mimeType = servletContext.getMimeType(filename);
        //Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
        response.setHeader("content-type",mimeType);
        //user-agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
        String agent = request.getHeader("user-agent");
        //使用工具类方法编码文件名即可
        filename = DownLoadUtils.getFileName(agent, filename);
		//设置超链接以什么方式来打开文件,attachment表示以附件的形式
        response.setHeader("content-disposition", "attachment;filename=" + filename);
        //通过response来获取输出流,获取的输出流在请求结束后会自动销毁,所以不用释放。
        //获取输出流,将输入流的数据写入到输出流中
        ServletOutputStream outputStream = response.getOutputStream();
        byte[] bytes = new byte[2048];
        int length = 0;
        while ( (length = fileInputStream.read(bytes)) != -1){
            outputStream.write(bytes,0,length);
        }

        fileInputStream.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

用到的DownLoadUtils 工具类

作用:将浏览器的版本型号和文件传入,通过浏览器的版本型号来获取指定的编码方式,并将文件重新编码返回。

public class DownLoadUtils {
    public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}