创建时间:6.19 & 6.24

1.案例-完成文件下载

1)  什么情况下会文件下载?

浏览器不能解析的文件就下载

*使用a标签直接指向服务器上的资源

2)什么情况下需要在服务端编写文件下载的代码?

理论上,浏览器可以解析的代码需要编写文件下载代码

实际开发中,只要是下载的文件都编写文件下载代码

文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端。所以文件下载需要IO技术将服务器端的文件使用InputStream读取到,在使用      ServletOutputStream写到response缓冲区中

代码如下:

上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上,而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方式。

1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);

2)告示浏览器文件的打开方式是下载:

response.setHeader("Content-Disposition","attachment;filename=文件名称");

代码如下:

*客户端不是根据文件扩展名来区分文件的类型,而是通过文件的MIME类型(在tomcat的web.xml中对extension进行MIME的映射)

但是,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,  原因是不同的浏览器默认对下载文件的编码方式不同,ie是UTF-8编码方式,而火狐浏览器是Base64编码方式。所里这里需要解决浏览器兼容性问题,解决浏览器兼容   性问题的首要任务是要辨别访问者是ie还是火狐(其他),通过Http请求体中的一个属性可以辨别

解决乱码方法如下(不要记忆--了解):

其中agent就是请求头User-Agent的值

 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");                    

 }

完整代码:见WEB14代码DownloadServlet2.java

 package com.itheima.content;

 import java.io.FileInputStream;

 import java.io.IOException;

 import java.io.InputStream;

 import java.net.URLEncoder;

 import javax.servlet.ServletException;

 import javax.servlet.ServletOutputStream;

 import javax.servlet.http.HttpServlet;

 import javax.servlet.http.HttpServletRequest;

 import javax.servlet.http.HttpServletResponse;

 import sun.misc.BASE64Encoder;

 public class DownLoadServlet2 extends HttpServlet {

       protected void doGet(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

             //*******文件名称是中文的下载*******

             //获得要下载的文件的名称

             String filename = request.getParameter("filename");//????.jpg

             //解决获得中文参数的乱码----下节课讲

             filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//美女.jpg

             //获得请求头中的User-Agent

             String agent = request.getHeader("User-Agent");

             //根据不同浏览器进行不同的编码

             String filenameEncoder = "";

             if (agent.contains("MSIE")) {

                   // IE浏览器

                   filenameEncoder = URLEncoder.encode(filename, "utf-8");

                   filenameEncoder = filenameEncoder.replace("+", " ");

             } else if (agent.contains("Firefox")) {

                   // 火狐浏览器

                   BASE64Encoder base64Encoder = new BASE64Encoder();

                   filenameEncoder = "=?utf-8?B?"

                              + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

             } else {

                   // 其它浏览器

                   filenameEncoder = URLEncoder.encode(filename, "utf-8");                  

             }

             //要下载的这个文件的类型-----客户端通过文件的MIME类型去区分类型

             response.setContentType(this.getServletContext().getMimeType(filename));

             //告诉客户端该文件不是直接解析 而是以附件形式打开(下载)----filename="+filename 客户端默认对名字进行解码

             response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);

             //获取文件的绝对路径

             String path = this.getServletContext().getRealPath("download/"+filename);

             //获得该文件的输入流

             InputStream in = new FileInputStream(path);

             //获得输出流---通过response获得的输出流 用于向客户端写内容

             ServletOutputStream out = response.getOutputStream();

             //文件拷贝的模板代码

             int len = 0;

             byte[] buffer = new byte[1024];

             while((len=in.read(buffer))>0){

                   out.write(buffer, 0, len);

             }

             in.close();

             //out.close();

       }

       protected void doPost(HttpServletRequest request, HttpServletResponse response)

                   throws ServletException, IOException {

             doGet(request, response);

       }

 }

response细节点:

1)response获得的流不需要手动关闭,web容器(tomcat)会帮助我们关闭

2)getWritergetOutputStream不能同时调用

验证码案例:不用掌握生成验证码,只要掌握html页面里怎么改

[转]【HttpServlet】HttpServletResponse接口 案例:完成文件下载的更多相关文章

  1. HttpServletRequest 接口、HttpServletResponse 接口、请求转发与重定向

    上篇文章我们讲了servlet的基本原理,这章将讲一下剩余的部分. HttpServletRequest 接口 该接口是 ServletRequest 接口的子接口,封装了 HTTP 请求的相关信息, ...

  2. Servlet(6)—HttpServletRequest接口和HttpServletResponse接口

    HttpServletRequest接口和HttpServletResponse接口是继承ServletRequest和ServletResponse接口,是他们的子接口,但是我们在程序中进程看到Se ...

  3. HttpServletRequest HttpServletResponse接口详解

    HttpServletRequest接口最常用的方法就是获得请求中的参数,这些参数一般是客户端表单中的数据.同时,HttpServletRequest接口可以获取由客户端传送的名称,也可以获取产生请求 ...

  4. Yarn的Tool接口案例

    目录 Yarn的Tool接口案例 Tool接口环境准备 1 新建Maven项目YarnDemo 编写代码 打包jar上传到集群 Yarn的Tool接口案例 Tool接口环境准备 之前写wordcoun ...

  5. HttpServletResponse接口详解

    在 Servlet API 中,定义了一个 HttpServletResponse 接口,它继承自 ServletResponse 接口.HttpServletResponse 对象专门用来封装 HT ...

  6. HttpServletResponse接口

    public interface HttpServletResponse extends ServletResponse 描述一个返回到客户端的HTTP回应.这个接口允许Servlet程序员利用HTT ...

  7. Servlet--HttpServletRequest接口,HttpServletResponse接口

    HttpServletRequest接口 定义 public interface HttpServletRequest extends ServletRequest; 用来处理一个对 Servlet ...

  8. JavaWeb案例: 文件下载 基于tomcat8 默认编码为UTF-8

    package cn.itcast.download; import javax.servlet.ServletException; import javax.servlet.ServletOutpu ...

  9. [转]【response】HttpServletResponse接口

    创建时间:6.19 & 6.24 1.HttpServletResponse概述 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参 ...

随机推荐

  1. 关于对pei

    我现在才开始整理这个不算晚吧...... 望轻喷 学习博客 我们需要四个程序 1.暴力 2.“正解” 3.数据生成器 4.检查程序 暴力: 就是暴力 eg: #include <cstdio&g ...

  2. 【2019.7.26 NOIP模拟赛 T1】数字查找(figure)(数学)

    推式子 我们设\(n=kp+w\),则: \[(kp+w)a^{kp+w}\equiv b(mod\ p)\] 将系数中的\(kp+w\)向\(p\)取模,指数中的\(kp+w\)根据欧拉定理向\(p ...

  3. 【LG5330】[SNOI2019]数论

    [LG5330][SNOI2019]数论 题面 洛谷 题目大意: 给定集合\(\mathbb {A,B}\) 问有多少个小于\(T\)的非负整数\(x\)满足:\(x\)除以\(P\)的余数属于\(\ ...

  4. beeline无密码连接hiveserver2

    1.说明 #hiveserver2增加了权限控制,需要在hadoop的配置文件中配置 core-site.xml 增加以下内容: <property> <name>hadoop ...

  5. CentOS7 Zookeeper 安装

    集群部署 192.168.38.6  zk01192.168.38.7  zk02192.168.38.8  zk03 安装zookeeper,必须安装jdk. 1.下载 $ cd /usr/loca ...

  6. kubernetes实战(九):k8s集群动态存储管理GlusterFS及使用Heketi扩容GlusterFS集群

    1.准备工作 所有节点安装GFS客户端 yum install glusterfs glusterfs-fuse -y 如果不是所有节点要部署GFS管理服务,就在需要部署的节点上打上标签 [root@ ...

  7. 去掉DataGridView最后一行的空白行,删除空白行

    //不显示出dataGridView1的最后一行空白   dataGridView1.AllowUserToAddRows = false;       直接在LODE事件

  8. PDMan-2.1.0 正式发布:用心开源,免费的国产数据库建模工具 PowerDesigner

    PDMan是一款开源免费的数据库模型建模工具,支持Windows,Mac,Linux等操作系统,是PowerDesigner之外,更好的免费的替代方案.他具有颜值高,使用简单的特点.包含数据库建模,灵 ...

  9. alicebot

    一.   为什么Alice不支持中文因为Alice的question都会被bitoflife.chatterbean.text.Transformations类中的fit函数过滤,而过滤的表达式就是: ...

  10. Vue官方文档笔记(二)

    23.$refs是什么东东? 通过在标签上设置ref属性,然后在Vue实例方法中可以通过$refs拿到这些标签,如: <input ref="input"> metho ...