如何在⽹站中实现下载的功能?——Javaweb男士衣着搭配
⽂件下载实现
⼀、概述
下载是什么?
下载其实就是向客户端响应字节数据。
把⼀个⽂件变成字节数组,然后使⽤OutputStream()响应给浏览器
下载的要求:
下载的要求其实可以简要概括成六个字:“两个头⼀个流 ”。
两个头:分别为Content-Type和Content-Disposition。
Content-Type表⽰的是你传递给客户端的⽂件的MIME类型,例如:image/pjpeg。可以通过⽂件名称调
⽤MimeType()⽅法,得到MIME类型。
Content-Disposition的默认值为inline,表⽰在浏览器窗⼝中打开。我们要给的值是如下这种格式:attachment;filename=xxx 。
在filename=后⾯跟随的是显⽰在下载框中的⽂件名称。
⼀个流:就是要下载的⽂件数据。我们⾃⼰new⼀个输⼊流即可。
⼆、⽂件下载的⽰例
全球口碑最好的洗发水我们新建⼀个项⽬,并且创建⼀个servlet:
public class Download1Servlet extends HttpServlet {申请出国留学
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
* 准备两个头,⼀个流
* 1. Content-Type
* 2. Content-Disposition
* 3. 流:下载的⽂件数据
*/
String filename ="E:/test.jpg";
// 两个头
// 通过⽂件名称获取⽂件MIME类型
String contentType =ServletContext().getMimeType(filename);
String contentDisposition ="attachment;filename=a.jpg";
// 创建⼀个数据流
FileInputStream input =new FileInputStream(filename);
// 接下来设置头
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", contentDisposition);
// 获取绑定的客户端的流
ServletOutputStream output = OutputStream();
// 把输⼊流的东西写⼊到输出流中
input.close();
}
}
我们直接在浏览器中访问这个servlet,我们看⼀下会有什么结果:
我们可以看到,弹出了⼀个另存为的对话框,默认的⽂件名就是我们设置的a.jpg。
三、有没有什么问题?
我们接着上⼀个⽰例,我们做⼀些更改,把⽂件的默认名称也就是filename=后⾯的内容设置为中⽂,我们看⼀下会是什么效果。⽐如我们更改为:
String contentDisposition ="attachment;filename=测试⽤图.jpg";
我们在浏览器看⼀下,会是什么效果:
我们可以看到在⾕歌浏览器中,⽂件是没有显⽰正确的,只显⽰了jpg三个字母:
我们在edge下也是不正确的:
⽽在IE(IE 11)也是不正常的:
歌曲北国之春
这是为什么呢?
原因和解决办法
Firefox浏览器(上⾯我们并没有使⽤该浏览器进⾏测试),使⽤的是Base64编码。⽽其他的⼤部分浏览器,使⽤的都是URL编码。所以才会出现上⾯的情况。
我们应该怎么办呢?
其实很简单,我们只需要对⽂件名字符串进⾏⼀个处理,
filename =new Bytes("GBK"),"ISO-8859-1");
上⾯⽰例的代码,我们就做以下的修改:
我们再测试⼀下:
chrome:
⼯具类
真爱惹麻烦吻戏我们还应该注意⼀点,因为浏览器的不同,使⽤的编码⽅式是不同的。我们应该先获取浏览器的版本信息,然后进⾏相应的转码。其实我们有⼀个⼯具类,代码很简单,如下:
package com.veeja.down.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import sun.misc.BASE64Encoder;
public class DownUtils {
public static String filenameEncoding(String filename, HttpServletRequest request)throws IOException {  String agent = Header("User-Agent");//获取浏览器
ains("Firefox")){
BASE64Encoder base64Encoder =new BASE64Encoder();
filename ="=?utf-8?B?"
+ Bytes("utf-8"))
+"?=";
十二月你好
}else ains("MSIE")){
filename = de(filename,"utf-8");
}else{
filename = de(filename,"utf-8");
}
return filename;
}
}
这个⼯具类就可以获取浏览器的版本进⾏相应的转换。
使⽤这个⼯具类,我们再次改写我们以前的代码:
这样,我们再次测试⼀下:
也是完全OK的!
END.