
文件下载案例
发布日期:2021-05-07 19:41:31
浏览次数:20
分类:精选文章
本文共 4418 字,大约阅读时间需要 14 分钟。
文章目录
一、案例分析
文件下载需求:
(1)页面显示超链接(2)点击超链接后弹出下载提示框(3)完成图片文件下载
分析:
(1)超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求(2)任何资源都必须弹出下载提示框(3)使用响应头设置资源的打开方式:实现下载资源弹出提示框的需求 * content-disposition:attachment;filename=xxx
步骤:
(1)定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename(2)定义Servlet * 获取文件名称 * 使用字节输入流加载文件进内存 * 指定response的响应头: content-disposition:attachment;filename=xxx * 将数据写出到response输出流
二、代码分析
- 定义 download.html
Title 图片视频
图片视频
- 定义 DownloadServlet.java
@WebServlet("/downloadServlet")public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1找到文件服务器路径 ServletContext servletContext = this.getServletContext(); //这里的目录实际在 WEB 下的 img 所以这里使用/img/ 的形式 String realPath = servletContext.getRealPath("/img/" + filename); //2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); //3.设置response的响应头,需要设置两部分 //3.1设置响应头类型:content-type String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型 response.setHeader("content-type",mimeType); //3.2设置响应头打开方式:content-disposition //这里的filename表示下载弹出框的文件名 response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到输出流中 ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; //意思每次将内容读到byte数组中,同时返回读入的个数 while((len = fis.read(buff)) != -1){ sos.write(buff,0,len); } fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); }}
三、解决中文文件名下载问题
存在个问题如果这里的文件名为中文,弹出的下载框不能识别

* 解决思路: * 获取客户端使用的浏览器版本信息 * 根据不同的版本信息,设置filename的编码方式不同
@WebServlet("/downloadServlet")public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求参数,文件名称 String filename = request.getParameter("filename"); //2.使用字节输入流加载文件进内存 //2.1找到文件服务器路径 ServletContext servletContext = this.getServletContext(); //这里的目录实际在 WEB 下的 img 所以这里使用/img/ 的形式 String realPath = servletContext.getRealPath("/img/" + filename); //2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); //3.设置response的响应头,需要设置两部分 //3.1设置响应头类型:content-type String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型 response.setHeader("content-type",mimeType); //3.2设置响应头打开方式:content-disposition //解决中文文件名问题 //1.获取user-agent请求头、 String agent = request.getHeader("user-agent"); //2.使用工具类方法编码文件名即可 filename = DownLoadUtils.getFileName(agent, filename); //表示下载弹出框的文件名 response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到输出流中 ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; //意思每次将内容读到byte数组中,同时返回读入的个数 while((len = fis.read(buff)) != -1){ sos.write(buff,0,len); } fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); }}
DownLoadUtils.java
import sun.misc.BASE64Encoder;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { 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"); } return filename; }}
需要注意配合火狐浏览器的sun.misc.BASE64Encoder
只能在 jdk 9 之前的版本使用

发表评论
最新留言
不错!
[***.144.177.141]2025年04月12日 12时03分14秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
239. 滑动窗口最大值
2021-05-09
纵览全局的框框——智慧搜索
2021-05-09
手把手教你如何快速构建应用内消息推送与运营能力
2021-05-09
快服务流量之争:如何在快服务中占领一席之地
2021-05-09
【活动】直播揭秘<如何从0开发HarmonyOS硬件>
2021-05-09
Cocos平台集成AGC性能管理(二)—— 性能管理SDK集成
2021-05-09
华为推送服务 | 简单一招,提高用户活跃和留存
2021-05-09
基于Cocos SDKHub接入华为HMS Game服务—打包上架流程
2021-05-09
Unity平台 | 快速集成华为性能管理服务
2021-05-09