下载
1. 下载就是向客户端响应字节数据!
原来我们响应的都是html的字符数据!
把一个文件变成字节数组,使用response.getOutputStream()来各应给浏览器!!!
2. 下载的要求
* 两个头一个流!
> Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg
* 通过文件名称调用ServletContext的getMimeType()方法,得到MIME类型!
> Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开,
有的浏览器哦是打开下载框!attachment;filename=xxx 弹出框的文件名称,就是xxx
* 在filename=后面跟随的是显示在下载框中的文件名称!
> 流:要下载的文件数据!
* 自己new一个输入流即可!
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>download1</servlet-name>
<servlet-class>cn.itcast.web.servlet.Download1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>download1</servlet-name>
<url-pattern>/down1</url-pattern>
</servlet-mapping>
</web-app>
public class Download1Servlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 两个头一个流
* 1. Content-Type
* 2. Content-Disposition
* 3. 流:下载文件的数据
*/
String filename = "e:/许端阳.mp3";
String contentType = this.getServletContext().getMimeType(filename);//通过文件名称获取MIME类型
String contentDisposition = "attachment;filename=许端阳.mp3";
// 一个流
FileInputStream input = new FileInputStream(filename);//把文件变成一个流
//设置头
resp.setHeader("Content-Type", contentType);
resp.setHeader("Content-Disposition", contentDisposition);
// 获取绑定了响应端的流
ServletOutputStream output = resp.getOutputStream();
IOUtils.copy(input, output);//把输入流FileInputStream input中的数据写入到输出流ServletOutputStream output中。
input.close();
}
String contentDisposition = "attachment;filename=许端阳.mp3"; 如果filename 没有进行编码的话
文件的名称是没有名字是乱码
处理这个问题的方法是
* FireFox:Base64编码。
* 其他大部分浏览器:URL编码。
通用方案:filename = new String(filename.getBytes("GBK"), "ISO-8859-1");
修改以后的演示
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 两个头一个流
* 1. Content-Type
* 2. Content-Disposition
* 3. 流:下载文件的数据
*/
String filename = "e:/许端阳.mp3";
String freamname = new String("许端阳.mp3".getBytes("GBK"), "ISO-8859-1");
String contentType = this.getServletContext().getMimeType(filename);//通过文件名称获取MIME类型
String contentDisposition = "attachment;filename="+freamname;
// 一个流
FileInputStream input = new FileInputStream(filename);//把文件变成一个流
//设置头
resp.setHeader("Content-Type", contentType);
resp.setHeader("Content-Disposition", contentDisposition);
// 获取绑定了响应端的流
ServletOutputStream output = resp.getOutputStream();
IOUtils.copy(input, output);//把输入流FileInputStream input中的数据写入到输出流ServletOutputStream output中。
input.close();
}
这种方式也是好用的,但是可能对于一些特殊字符是不管用的,只能是用下面那种方法
// 用来对下载的文件名称进行编码的!
public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
String agent = request.getHeader("User-Agent"); //获取浏览器
if (agent.contains("Firefox")) {//由于base64 只有火狐浏览器是有问题的
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8"))
+ "?=";
} else if(agent.contains("MSIE")) {//微软的其他浏览器就是和采用的都是同样的url 编码
filename = URLEncoder.encode(filename, "utf-8");
} else {
filename = URLEncoder.encode(filename, "utf-8");
}
return filename;
}