创建时间: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. (转)yum只下载不安装软件包

    方法一:使用yum的downloadonly插件 步骤: (1) 先安装downloadonly插件  yum install yum-plugin-downloadonly (2)使用–downlo ...

  2. Ubuntu 14.04 apt-get update失效解决(转)

    现象如下: VirtualBox:~$ sudo apt-get update Err http://mirrors.aliyun.com trusty InRelease Err http://mi ...

  3. intelliJ 社区版-找不到 plugins选项

    丢人了... 今天 在intelliJ社区版上面找不到 plugins 选项了, 其实是有的,我看的是项目的 settings 当然没有了, (1)如果直接点击File==> 这样就是没有plu ...

  4. 解决Spring Cloud中Feign第一次请求失败的问题

    在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 com.netflix.hystrix.exception.HystrixTimeoutE ...

  5. go-gin-api 路由中间件 - Jaeger 链路追踪

    概述 首先同步下项目概况: 上篇文章分享了,路由中间件 - Jaeger 链路追踪(理论篇). 这篇文章咱们分享:路由中间件 - Jaeger 链路追踪(实战篇). 说实话,这篇文章确实让大家久等了, ...

  6. vm ------ 安装

    虚拟机(英语:virtual machine),在计算机科学中的体系结构里,是指一种特殊的软件,可以在计算机平台和终端用户之间创建一种环境,而终端用户则是基于这个软件所创建的环境来操作软件. 虚拟机最 ...

  7. mysql获取日期语句汇总

    汇总一些MySQL获取日期的SQL语句. -- 今天 SELECT DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00') AS '今天开始'; SELECT DATE_FORM ...

  8. scala中的Option

    Scala中Option是用来表示一个可选类型 什么是可选? --> 主要是指 有值(Some) 和 无值(None)-->Some和None是Option的子类 val myMap:Ma ...

  9. 【题解】L 国的战斗续之多路出击 [P2129]

    [题解]L 国的战斗续之多路出击 [P2129] 传送门: \(L\) 国的战斗续之多路出击 \([P2129]\) [题目描述] 给出 \(n\) 个坐标,\(m\) 个指令,指令处理顺序应是从后往 ...

  10. 【linux】CentOS 6 使用cron定时任务,报错:Redirecting to /bin/systemctl restart crond.service

    在centos7上,执行cron定时任务的相关命令,反馈如下: 定时任务执行,反馈是: Redirecting to /bin/systemctl restart crond.service 原因: ...