• Resonse9_ServletContext3


    1. 概念

      ServletContext对象代表整个web应用,可以和程序的容器(服务器)来通信。

      定义一组方法,servlet 使用这些方法与其 servlet 容器进行通信

    2. 获取ServletContext对象

        a. 通过request对象获取:request.getServletContext();

     b. 通过HttpServlet获取:this.getServletContext(); 继承HttpServlet的类通过这种方法获取。

     c. 代码实现

    package cn.itcast.web.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("/servletContextDemo1")
    public class ServletContextDemo1 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            /*
            获取ServletContext对象
            a. 通过request对象获取
                request.getServletContext();
            b. 通过HttpServlet获取:
                this.getServletContext();继承HttpServlet的类通过这种方法获取。
             */
            //1. 通过request对象获取
            ServletContext context1 = request.getServletContext();
            //2. 通过HttpServlet获取
            ServletContext context2 = this.getServletContext();
    
            System.out.println(context1);
            System.out.println(context2);
    
            System.out.println(context1 ==  context2);
    
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

      浏览器访问http://localhost/day09/servletContextDemo1,检查idea控制台输出结果,可以看到两种方法获取的ServletContext对象的地址值是一样的,即ServletContext对象是同一个。

      

    3. ServletContext对象功能

      1. 获取MIME类型:

        * MIME类型:在互联网通信过程中定义的一种文件数据类型,MIME 类型由 servlet 容器的配置(tomcat-conf-web.xml)确定,可以在 Web 应用程序部署描述符中指定。

          * 格式: 大类型/小类型 text/html image/jpeg

        * 获取MIME类型:String getMimeType(String file),file为指定文件名称的String

        * 代码实现

    package cn.itcast.web.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("/servletContextDemo2")
    public class ServletContextDemo2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            /*
             1. 获取MIME类型:
            * MIME类型:在互联网通信过程中定义的一种文件数据类型
                * 格式: 大类型/小类型 text/html image/jpeg
            * 获取MIME类型:String getMimeType(String file)
             */
    
            //2. 通过HttpServlet获取
            ServletContext context = this.getServletContext();
            //3. 定义文件名称
            String filename ="a.jpg";
    
            //4. 获取MIME类型
            String mimeType = context.getMimeType(filename);
            System.out.println(mimeType);//image/jpeg
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

         浏览器访问http://localhost/day09/servletContextDemo2,检查idea控制台输出结果:image/jpeg    

      2. 域对象:共享数据

        ServletContext对象是域对象

        1. setAttribute(String name,Object value)

        2. getAttribute(String name)

        3. removeAttribute(String name) 

        * ServletContext对象范围:所有用户所有请求的数据,可共享数据。不建议使用,因为范围大存在安全问题。

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

        方法:String getRealPath(String path),path为虚拟路径

          

    package cn.itcast.web.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.File;
    import java.io.IOException;
    
    @WebServlet("/servletContextDemo5")
    public class ServletContextDemo5 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            /*
             1. 获取MIME类型:
            * MIME类型:在互联网通信过程中定义的一种文件数据类型
                * 格式: 大类型/小类型 text/html image/jpeg
            * 获取MIME类型:String getMimeType(String file)
             */
    
            //2. 通过HttpServlet获取
            ServletContext context = this.getServletContext();
    
            //获取文件的服务器路径
            String b = context.getRealPath("/b.txt");//web目录下的资源访问
            System.out.println(b);
    
            String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
            System.out.println(c);
    
            String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
            System.out.println(a);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

          浏览器访问 http://localhost/day09/servletContextDemo5,检查idea控制台输出结果:

          

    4. 案例

     文件下载需求:

       1、页面显示超链接

       2、点击超链接后弹出下载提示框

       3、完成图片文件下载

      分析:

       1、超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求

       2、需求是任何资源都必须弹出下载提示框

       3、使用响应头设置资源的打开方式:
          * content-disposition:attachment;filename=xxx

      步骤:

       1、定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename

       2、定义Servlet

        i. 获取文件名称

        ii. 使用字节输入流加载文件进内存

        iii. 指定response的响应头: content-disposition:attachment;filename=xxx

        iiii. 将数据写出到response输出流

      问题:

       * 中文文件问题

         * 解决思路:

          1. 获取客户端使用的浏览器版本信息

              String agent = request.getHeader("user-agent");

          2. 根据不同的版本信息,设置filename的编码方式不同

              使用工具类编码文件:filename = DownLoadUtils.getFileName(agent,filename);

      实现:

       web目录下新建一个download.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <a href="/day09/img/1.jpg">图片1</a>
    
        <a href="/day09/img/1.avi">视频1</a>
        <hr>
        <a href="/day09/downloadServlet?filename=1.jpg">图片2</a>
    
        <a href="/day09/downloadServlet?filename=1.avi">视频2</a>
    
    </body>
    </html>

       新建Servlet:DownloadServlet

    package cn.itcast.web.download;
    
    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 {
        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 fis = new FileInputStream(realPath);
    
            //3. 设置response的响应头
            //3.1 设置响应头类型:content-type
            String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
            response.setContentType(mimeType);
    
            //3.2 设置响应头打开方式:content-disposition
            response.setHeader("content-disposition","attachment;filename="+filename);//提示框名字
    
            //4. 将输入流的数据写出到输出流中
            ServletOutputStream sos = response.getOutputStream();
            byte[] buff = new byte[1024*8];
            int len = 0;
            while ((len = fis.read(buff)) != -1){
                sos.write(buff,0,len);
            }
    
            fis.close();
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

        浏览器访问http://localhost/day09/download.html,检查浏览器展示,点击“图片1”会直接展示图片,点击“视频1”会提示保存/下载视频,因为浏览器可以直接解析图片不能直接解析视频。

        点击“图片2”会弹出图片下载框,点击“视频2”会弹出视频下载框,点击确定下载成功。

        

      若download.html中的文件名为中文,即/day09/downloadServlet?filename=九尾.jpg,则下载框中的文件名为乱码。解决办法如下:

    package cn.itcast.web.utils;
    
    //import sun.misc.BASE64Encoder;
    import Decoder.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;
        }
    }
    package cn.itcast.web.download;
    
    import cn.itcast.web.utils.DownLoadUtils;
    
    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 {
        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 fis = new FileInputStream(realPath);
    
            //3. 设置response的响应头
            //3.1 设置响应头类型:content-type
            String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
            response.setContentType(mimeType);
    
            //3.2 设置响应头打开方式:content-disposition
    
            //解决中文文件名问题
            //1. 获取user-agent请求头
            String agent = request.getHeader("user-agent");
            //2. 使用工具类编码文件名即可
            filename = DownLoadUtils.getFileName(agent, filename);
            response.setHeader("content-disposition","attachment;filename="+filename);//提示框名字
    
            //4. 将输入流的数据写出到输出流中
            ServletOutputStream sos = response.getOutputStream();
            byte[] buff = new byte[1024*8];
            int len = 0;
            while ((len = fis.read(buff)) != -1){
                sos.write(buff,0,len);
            }
    
            fis.close();
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request,response);
        }
    }

        浏览器访问http://localhost/day09/download.html,检查浏览器展示,点击“图片2”会弹出图片下载框:展示中文文件名

  • 相关阅读:
    jquery checkbox的相关操作——全选、反选、获得所有选中的checkbox
    js 跳转页面 刷新页面
    一些基本的正则- 手机号正则,邮箱正则,数字正则,字母正则,汉子正则,身份证正则.等
    vue 中使用 国际化(i18n)
    nvm 下载node不会自动下载npm
    angular 自定义组件和form的formControlName 连用
    angular8 搜索组件封装
    vscode 设置缩进 4
    滚动条样式设置
    使用vscode 1. 报在签出前,请清理储存库工作树. 2.拉取代码报错
  • 原文地址:https://www.cnblogs.com/ajing2018/p/15934128.html
Copyright © 2020-2023  润新知