• ServletContext 对象的学习笔记


    ServletContext对象概述

    ServletContext用来存放全局变量,每个Java虚拟机每个Web项目只有一个ServletContext,这个ServletContext是由Web服务器创建的,来保证它的唯一性。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象通讯。ServletContext对象通常也被称之为Context域对象。

    • 获取方式

      • 通过request对象获取

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

        this.getServletContext();
        

    获取ServletContext对象

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo01")
    public class ServletContextDemo01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 通过 Request 对象获取 ServletContext 对象
            ServletContext requestServletContext = request.getServletContext();
            // 通过 HttpServlet 获取 ServletContext 对象
            ServletContext servletContext = this.getServletContext();
            System.out.println(requestServletContext);
            System.out.println(servletContext);
            System.out.println(requestServletContext == servletContext);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    启动服务器,浏览器访问:http://localhost:8080/ServletContext_war_exploded/demo01

    控制台输出:

    org.apache.catalina.core.ApplicationContextFacade@86cb2b8
    org.apache.catalina.core.ApplicationContextFacade@86cb2b8
    true
    

    ServletContext对象功能

    1. 获取MIME类型

      • MIME类型:在互联网通信过程中定义的一种文件数据类型

        如:大类型/小类型 text/html image/jpeg

      • 获取方法:

        String getMimeType(String file) 
        
    2. 域对象:共享数据

      setAttribute(String name,Object value)
      getAttribute(String name)
      removeAttribute(String name)
      
    3. 获取文件的真实(服务器)路径

      String getRealPath(String path)
      

    获取mime 类型

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo02")
    public class ServletContextDemo02 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 通过 HttpServlet 获取 ServletContext 对象
            ServletContext servletContext = this.getServletContext();
            // 定义文件名称
            String fileName01 = "a.png";
            String fileName02 = "b.jpeg";
            // 获取 MIME 类型
            String mimeType01 = servletContext.getMimeType(fileName01);
            System.out.println(mimeType01);
            String mimeType02 = servletContext.getMimeType(fileName02);
            System.out.println(mimeType02);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    启动服务器,浏览器访问:http://localhost:8080/ServletContext_war_exploded/demo02

    控制台输出:

    image/png
    image/jpeg
    

    域对象:共享数据

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo03")
    public class ServletContextDemo03 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 通过 HttpServlet 获取 ServletContext 对象
            ServletContext servletContext = this.getServletContext();
            // 设置数据
            servletContext.setAttribute("demo03's data", "我是demo03这里设置的数据!!!");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo04")
    public class ServletContextDemo04 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 通过 HttpServlet 获取 ServletContext 对象
            ServletContext servletContext = this.getServletContext();
            // 获取demo03中设置的数据
            System.out.println(servletContext.getAttribute("demo03's data"));
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    启动服务器,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo03,目的是,访问demo03,设置数据。

    然后,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo04。控制台输出:

    我是demo03这里设置的数据!!!
    

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

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/demo05")
    public class ServletContextDemo05 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 通过 HttpServlet 获取 ServletContext 对象
            ServletContext servletContext = this.getServletContext();
            // 获取文件的服务器路径
            System.out.println(servletContext.getRealPath("/file01.txt"));
            System.out.println(servletContext.getRealPath("/WEB-INF/file02.txt"));
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

    启动服务器,浏览器中访问:http://localhost:8080/ServletContext_war_exploded/demo05

    控制台输出:

    /Users/liyihua/IdeaProjects/ServletContext/out/artifacts/ServletContext_war_exploded/file01.txt
    /Users/liyihua/IdeaProjects/ServletContext/out/artifacts/ServletContext_war_exploded/WEB-INF/file02.txt
    

    案例

    • 文件下载需求:

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

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

      1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
      2. 定义Servlet
        1. 获取文件名称
        2. 使用字节输入流加载文件进内存
        3. 指定response的响应头: content-disposition:attachment;filename=xxx
        4. 将数据写出到response输出流
      • 问题:
        • 中文文件问题
          • 解决思路:
            1. 获取客户端使用的浏览器版本信息
            2. 根据不同的版本信息,设置filename的编码方式不同
    • 实现:

      • java

        import javax.servlet.ServletContext;
        import javax.servlet.ServletException;
        import javax.servlet.ServletOutputStream;
        import javax.servlet.annotation.WebServlet;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.io.FileInputStream;
        import java.io.IOException;
        
        @WebServlet("/downloadServlet")
        public class DownloadServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                // 获取用户请求参数(文件名称)
                String fileName = request.getParameter("filename");
                // 获取 ServletContext 对象
                ServletContext servletContext = request.getServletContext();
        
                // 根据文件名称,找到服务器中文件的路径
                String filePath = servletContext.getRealPath("/downloadFile/" + fileName);
                // 根据文件名称,获取文件类型
                String mimeType = servletContext.getMimeType(fileName);
        
                // 设置 response 的响应头 —————— 响应头类型:content-type
                response.setHeader("content-type", mimeType);
                // 响应头的打开方式:content-disposition
                response.setHeader("content-disposition", "attachment;filename=" + fileName);
        
                // 使用字节输入流加载文件进内存
                FileInputStream fileInputStream = new FileInputStream(filePath);
                // 将字节输入流的数据写出到输出流中
                ServletOutputStream responseOutputStream = response.getOutputStream();
                byte[] bytes = new byte[1024 * 8];
                int len = 0;
                while ((len = fileInputStream.read(bytes)) != -1) {
                    responseOutputStream.write(bytes, 0, len);
                }
                fileInputStream.close();
            }
        
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
                this.doGet(request, response);
            }
        }
        
      • html

        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <!-- 虚拟路径:/ResponseDownload_war_exploded -->
            <!-- /downloadServlet 为Servlet的访问路径 -->
            <!-- 资源名称:image06.png、view.avi -->
            <a href="/ResponseDownload_war_exploded/downloadServlet?filename=image06.png">下载图片</a>
            <a href="/ResponseDownload_war_exploded/downloadServlet?filename=view.avi">下载视频</a>
        
        </body>
        </html>
        
      • 启动服务器,浏览器中访问:http://localhost:8080/ResponseDownload_war_exploded/download.html

        20200528221013

        点击下载图片,会下载: image06.png

        点击下载视频,会下载:view.avi


    参考文献

    1. ServletContext对象详解
    Good Good Write Bug, Day Day Up
  • 相关阅读:
    Kubernetes Admission Controller解析
    容器化Node Exporter对主机磁盘使用率的监控问题
    Prometheus监控指标的label注入方法
    Prometheus告警模型分析
    Kubernetes Controller执行框架解析
    深入理解Istio核心组件之Pilot
    Prometheus存储模型分析
    如何利用Prometheus监控你的应用
    Prometheus在Kubernetes下的服务发现机制
    JSON字符串和js对象转换
  • 原文地址:https://www.cnblogs.com/liyihua/p/14477501.html
Copyright © 2020-2023  润新知