我们先来看一个最简单的文件下载的例子:

 package com.yyz.response;

 import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//文件下载
public class ResponseDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String realpath = this.getServletContext().getRealPath("/download/1.gif");
String filename = realpath.substring(realpath.lastIndexOf("\\")+1);
response.setHeader("content-disposition", "attachment;filename="+filename);
//服务器通过这个头,告诉浏览器以下载方式打开数据
FileInputStream in = new FileInputStream(realpath);
int len = 0;
byte buffer[]=new byte[1024];
OutputStream out = response.getOutputStream();
while((len = in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
//out不用close,response在销毁的时候服务器会自动关闭与response相关的流。
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}

该段代码的功能是从服务器端下载图片1.png。目录结构用MyEclipse的package explorer显示如下:

让我们增加一点难度,我们要下载的文件是一个中文名字的文件。由于在http协议中头文件中的东西只能是ASCII字符,因而通过上述方式(直接将  String realpath = this.getServletContext().getRealPath("/download/1.gif");改为  String realpath = this.getServletContext().getRealPath("/download/图片.gif");)直接拿文件,

会出现乱码问题。附上测试结果:

要解决这个问题,要用到 URLEncoder类的encode方法:

 package com.yyz.response;

 import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//中文文件下载时,中文文件名要经过URL编码。
public class ResponseDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String realpath = this.getServletContext().getRealPath("/download/图片.gif");
String filename = realpath.substring(realpath.lastIndexOf("\\")+1);
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
//本函数将字符串以 URL 编码
FileInputStream in = new FileInputStream(realpath);
int len = 0;
byte buffer[]=new byte[1024];
OutputStream out = response.getOutputStream();
while((len = in.read(buffer))>0){
out.write(buffer, 0, len);
}
in.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}

附上测试结果:

另外这里有一个小细节需要大家注意:

不能用FileReader代替FileInputStream。用FileReader会丢失数据,原因是这样的:FileReader是字符流,而图片,媒体文件等的数据都是以01的方式存储,用FileReader读的时候需要查阅一个编码表,如果未指定一种编码,则使用相应平台的默认编码。如在中国的电脑就会去查GB2312。当读到GB2312码表中不存在的编码时,会将该数据编码成'?',结束后数据就变成中文和'?'的混合。发到客户端后显示时再次查阅码表,将所有的'?'替换成'?'的编码,就会丢失数据。向这种细节只需要记住一点:字节流可以处理任意类型的数据,字符流只能处理字符数据。

response小结(二)——文件下载的更多相关文章

  1. online QRcode generator , QRcode=== (Quick Response Code) , 二维条码,二维码,彩色二维码,图片二维码,

    online QRcode generator ,  QRcode=== (Quick Response Code)    , 二维条码,二维码,彩色二维码,图片二维码, 1 http://cli.i ...

  2. gulp使用小结(二)

    接上篇文章接Gulp使用小结(一) 内容如下: 首先,偶在gulp-demos上已经提交了个较通用的栗子...俺琢磨半天,原准备分阶段搞些 Gulp 套路,但是写完介个栗子之后,觉得已经能覆盖绝大多数 ...

  3. Vue学习小结(二)

    接上一批,小结(二). 三.导航内容(含左侧导航及顶部面包屑导航) 其实导航条主要根据element-ui的教程进行编写,官网:http://element-ui.cn/#/zh-CN/compone ...

  4. Struts2知识点小结(二)

    一.结果视图的配置    <result name="success">/success.jsp</result>        1.局部结果视图      ...

  5. python --- 字符编码学习小结(二)

    距离上一篇的python --- 字符编码学习小结(一)已经过去2年了,2年的时间里,确实也遇到了各种各样的字符编码问题,也能解决,但是每次都是把所有的方法都试一遍,然后终于正常.这种方法显然是不科学 ...

  6. Element Vue 开箱即用框架如何使用-测试开发【提测平台】阶段小结(二)

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 上一篇总结了后端服务接口的开发,这篇我们主要来总结下前后端分离开发中的前端部分,主要是开箱即用的框架介绍和之前章节组件的梳理和部分的扩展内 ...

  7. Nginx 利用 X-Accel-Redirect response.setHeader 控制文件下载

    nginx.conf location / { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP ...

  8. response小结(五)—通过response实现请求重定向

    请求重定向指的是一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向.302状态码和location头即可实现重定向. 请求重定向最常见的应用场景就是用户登录. 下面 ...

  9. response小结(四)

    1.发送http头,控制浏览器定时刷新网页(REFRESH). package com.yyz.response; import java.io.IOException; import javax.s ...

随机推荐

  1. mime type 概要介绍

    内容类型 内容类型(Content-Type),这个头部领域用于指定消息的类型.一般以下面的形式出现. Content-Type: [type]/[subtype]; parameter type t ...

  2. Mysql中关于 group_concat函数详解

    group_concat()主要功能:能将相同的行组合起来 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Sepa ...

  3. CentOS6.4 64位系统安装jdk

    1. CentOS操作安装好了以后,系统自带了openJDK,先查看相关的安装信息: $rpm -qa | grep java tzdata-java-2013b-1.el6.noarchjava-1 ...

  4. Parallax Occlusion Mapping

    如上图,本来是采样original texture coordinates点的颜色,其实却采样了correcter texture coordinates点的颜色. 而且会随着视线的不同看到凹凸程度变 ...

  5. 简谈java的split

    最近都在处理视频音频,今天在合成音频视频时为了给合成的新文件换个新名字,我打算获取了之前的视频名称,用split来分割出不带后缀的名字,再自己加上后缀. 众所周知split可以分割由某种字符分段的St ...

  6. JQuery ajax请求一直返回Error(parsererror)

    $.ajax({ type :"post", url :"busine_in.action", timeout : 40000, data: "cen ...

  7. Android Study ING

    http://bbs.csdn.net/topics/370249613 android的tools和adb命令 http://www.u148.net/article/102147.html htt ...

  8. 使用synchronize同步关键字来同步代码快

    1.synchronized关键字的作用域有二种: 1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有 ...

  9. Android 滑动效果高级篇(七)—— 华丽翻页效果

    By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前看到像ipad上的ibook的模拟书籍翻页的特效感觉很炫,在android上也有像laputa和ireader ...

  10. iOS开发——UI_swift篇&TableView自定义聊天界面

    TableView自定义聊天界面   1,下面是一个放微信聊天界面的消息展示列表,实现的功能有: (1)消息可以是文本消息也可以是图片消息 (2)消息背景为气泡状图片,同时消息气泡可根据内容自适应大小 ...