文件下载需求
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片、视频文件下载
分析
- 超链接指向的资源若为静态资源则能被浏览器直接解析,在浏览器上直接展示。若为动态资源则不能解析,则弹出下载提示框。不满足需求。
- 任何资源都必须弹出下载提示框(由于浏览器不同,响应的方式也不同)
- 使用响应头content-disposiition:attachment;filename=xxx(附件下载形式)
步骤
- 定义页面,编辑超链接href属性,指向servlet,传递资源名称filename
- 定义servlet
- 获取文件名称
- 使用字节输入流将文件加载进内存
- 指定response的响应头:content-disposition:attachment;filename=xxx
- 将数据写出到response输出流
代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>资源下载</title>
</head>
<body>
<a href="/img/1.jpg">图片</a>
<a href="/img/1.mp4">视频</a>
<hr>
<a href="downloadServlet?filename=1.jpg">图片</a>
<a href="downloadServlet?filename=1.mp4">视频</a>
</body>
</html>
Servlet
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getParameter("filename");
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
FileInputStream fis=new FileInputStream(realPath);
String mimeType = servletContext.getMimeType("filename");
response.setHeader("content-type",mimeType);
response.setHeader("content-disposition","attachment;filename="+filename);
ServletOutputStream sos = response.getOutputStream();
int len=0;
byte[]bys=new byte[1024];
while ((len=fis.read(bys))!=-1){
sos.write(bys,0,len);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
中文文件名问题
解决思路
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置filename的编码方式不同
代码
DownloadUtil编码
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Base64;
public class DownloadUtil {
public static String getFilename(String agent,String filename) throws UnsupportedEncodingException {
if (agent.contains("IE")){
//IE浏览器
filename= URLEncoder.encode(filename,"utf-8");
filename=filename.replace("+"," ");
}else if (filename.contains("Firefox")){
//火狐浏览器
Base64.Encoder encoder = Base64.getEncoder();
filename="-?utf-8?B?"+encoder.encode(filename.getBytes("utf-8"))+"?-";
}else {
filename=URLEncoder.encode(filename,"utf-8");
}
return filename;
}
}