ServletContext

1. ServletContext 对象的概念

ServletContext 对象代表整个 Web 应用,它可以和 Web 容器通信。

2. ServletContext 对象的获取

  1. 通过 Request 对象获取

    request.getServletContext();
    
  2. 通过 HttpServlet 获取

    this.getServletContext();
    

3. ServletContext 对象的功能

  1. 获取 MIME 类型

    1. MIME 类型的概念

      MIME 类型是在互联网通信过程中定义的一种文件数据类型,它是文件类型的标准

    2. MIME 类型的格式

      大类型/小类型
      

      例如:

      text/html	image/jpeg
      
    3. 获取 MIME 类型的方法

      • String getMimeType(String file)
    4. 获取 MIME 类型练习

      @WebServlet("/ServletContextDemo2")
      public class ServletContextDemo2 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 获取 ServletContext 对象
              ServletContext servletContext = this.getServletContext();
      
              // 定义文件名称
              String filename = "a.jpg";
      
              // 获取 MIME 类型
              String mimeType = servletContext.getMimeType(filename);
      
              System.out.println(mimeType);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doPost(request,response);
          }
      }
      

      运行结果:

      image/jpeg
      
  2. 域对象

    1. 域对象的功能

      用来共享数据

    2. 共享数据的范围

      所有用户所有请求的数据

    3. 方法

      1. 存储数据
        • void setAttribute(String name,Object obj)
      2. 通过键获取值
        • Object getAttribute(String name)
      3. 通过键移除键值对
        • void removeAttribute(String name)
    4. 共享数据的练习

      实现 ServletContextDemo3 和 ServletContextDemo4 共享数据

      @WebServlet("/ServletContextDemo3")
      public class ServletContextDemo3 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 获取 ServletContext 对象
              ServletContext servletContext = this.getServletContext();
      
              // 存储数据
              servletContext.setAttribute("value1","hello");
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doPost(request,response);
          }
      }
      
      
      @WebServlet("/ServletContextDemo4")
      public class ServletContextDemo4 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 获取 ServletContext 对象
              ServletContext servletContext = this.getServletContext();
      
              // 获取数据
              Object value1 = servletContext.getAttribute("value1");
      
              System.out.println(value1);
      
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doPost(request,response);
          }
      }
      
  3. 获取文件的真实(服务器)路径

    1. 方法

      • String getRealPath(String path)
    2. 获取文件的真实路径练习

      @WebServlet("/ServletContextDemo5")
      public class ServletContextDemo5 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 获取 ServletContext 对象
              ServletContext servletContext = this.getServletContext();
      
              // 获取 web 目录下的 c.txt 的真实路径
              String realPath1 = servletContext.getRealPath("a.txt");
              System.out.println(realPath1);
      
              // 获取 WEB-INF 目录下的 b.txt 的真实路径
              String realPath2 = servletContext.getRealPath("/WEB-INF/b.txt");
              System.out.println(realPath2);
      
              // 获取 src 目录下的 c.txt 的真实路径
              String realPath3 = servletContext.getRealPath("/WEB-INF/classes/b.txt");
              System.out.println(realPath3);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doPost(request,response);
          }
      }
      

4. 文件下载案例

  1. 需求分析

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

    1. 定义页面,编辑超链接 href 属性,指向 Servlet,设置请求参数,传递文件名称
    2. 定义 Servlet
    3. 获取请求参数,文件名称
    4. 使用字节输入流加载文件进内存
    5. 设置 response 的响应头
    6. 将输入流数据写出到 response 输出流
  3. 编码实现

    1. 定义页面

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
          <a href="/DownloadServlet?filename=1.jpg">图片1</a>
          <a href="/DownloadServlet?filename=2.jpg">图片2</a>
      </body>
      </html>
      
    2. 定义 Servlet

      @WebServlet("/DownloadServlet")
      public class DownloadServlet extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 1.获取请求参数,文件名称
              String filename = request.getParameter("filename");
      
              // 2.使用字节输入流加载文件进内存
              // 2.1 找到文件的真实路径
              ServletContext servletContext = this.getServletContext();
              String realPath = servletContext.getRealPath("/img/"+filename);
              // 2.2 用字节流关联
              FileInputStream fileInputStream = new FileInputStream(realPath);
      
              // 3. 设置 Response 的响应头
              // 3.1 获取文件类型
              String mimeType = servletContext.getMimeType(filename);
              // 3.2 设置响应头类型
              response.setHeader("Content-type",mimeType);
              // 3.3 设置响应头打开方式
              response.setHeader("Content-disposition","attachment;filename="+filename);
      
              //4.将输入流的数据写出到 response 输出流中
              ServletOutputStream outputStream = response.getOutputStream();
              byte[] buff = new byte[1024 * 8];
              int len = 0;
              while((len = fileInputStream.read(buff)) != -1){
                  outputStream.write(buff,0,len);
              }
      
              fileInputStream.close();
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doPost(request,response);
          }
      }
      
  4. 中文文件问题

    1. 问题

      如果文件名是中文,下载后的文件名称无法显示

    2. 解决思路

      1. 获取客户端使用的浏览器版本信息
      2. 根据不同的版本信息,设置 filename 的编码方式不同
    3. 解决步骤

      1. 创建一个 utils 包,在其中创建一个工具类 DownLoadUtils,它可以根据浏览器设置 filename 的编码

        package com.zt.web.utils;
        
        import sun.misc.BASE64Encoder;
        import java.io.UnsupportedEncodingException;
        import java.net.URLEncoder;
        
        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;
            }
        }
        
        
      2. 在 Servlet 中使用工具类方法编码文件名

        @WebServlet("/DownloadServlet")
        public class DownloadServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                // 1.获取请求参数,文件名称
                String filename = request.getParameter("filename");
                // 2.使用字节输入流加载文件进内存
                // 2.1 找到文件的真实路径
                ServletContext servletContext = this.getServletContext();
                String realPath = servletContext.getRealPath("/img/"+filename);
                // 2.2 用字节流关联
                FileInputStream fileInputStream = new FileInputStream(realPath);
        
                // 3. 设置 Response 的响应头
                // 3.1 获取文件类型
                String mimeType = servletContext.getMimeType(filename);
                // 3.2 设置响应头类型
                response.setHeader("Content-type",mimeType);
                // 3.3 解决中文文件名问题
                // 3.3.1.获取 user-agent 请求头
                String agent = request.getHeader("user-agent");
                // 3.3.2.使用工具类方法编码文件名即可
                filename = DownLoadUtils.getFileName(agent, filename);
                // 3.4 设置响应头打开方式
                response.setHeader("Content-disposition","attachment;filename="+filename);
        
                //4.将输入流的数据写出到 response 输出流中
                ServletOutputStream outputStream = response.getOutputStream();
                byte[] buff = new byte[1024 * 8];
                int len = 0;
                while((len = fileInputStream.read(buff)) != -1){
                    outputStream.write(buff,0,len);
                }
        
                fileInputStream.close();
            }
        
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request,response);
            }
        }
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ServletContext是Java Web中的一个重要接口,它代表了Web应用程序在服务器中的上下文环境。在一个Web应用程序中,每个Servlet都可以访问同一个ServletContext对象,从而实现Servlet之间的数据共享和通信。 在Java中,可以使用ServletConfig对象的getServletContext()方法来获取ServletContext对象,然后使用该对象的方法来实现一系列操作,例如: 1. 获取Web应用程序的初始化参数:可以使用ServletContext对象的getInitParameter()方法来获取Web应用程序的初始化参数,例如数据库连接等配置信息。 ```java String username = context.getInitParameter("username"); ``` 2. 获取Web应用程序的真实路径:可以使用ServletContext对象的getRealPath()方法来获取Web应用程序的真实路径,例如获取Web应用程序中的一个文件的绝对路径。 ```java String path = context.getRealPath("/WEB-INF/config.properties"); ``` 3. 在ServletContext中保存数据:可以使用ServletContext对象的setAttribute()方法来在ServletContext中保存数据,从而实现Servlet之间的数据共享。 ```java context.setAttribute("key", value); ``` 4. 从ServletContext获取数据:可以使用ServletContext对象的getAttribute()方法来从ServletContext获取数据,例如获取其他Servlet保存的数据。 ```java Object value = context.getAttribute("key"); ``` 需要注意的是,ServletContext对象的作用域为整个Web应用程序,因此需要注意数据的安全性和可靠性。另外,ServletContext对象是在Web应用程序启动时创建的,因此可以在Servlet的init()方法中获取ServletContext对象并进行初始化操作,例如读取配置文件等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bm1998

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

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

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

打赏作者

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

抵扣说明:

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

余额充值