使用HttpServletResponse提供文件下载
来源:互联网 发布:网络诈骗的危害性 编辑:程序博客网 时间:2024/05/21 10:03
文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载
文件下载功能的实现思路:
1.获取要下载的文件的绝对路径
2.获取要下载的文件名
3.设置content-disposition响应头控制浏览器以下载的形式打开文件
4.获取要下载的文件输入流
5.创建数据缓冲区
6.通过response对象获取OutputStream流
7.将FileInputStream流写入到buffer缓冲区
8.使用OutputStream将缓冲区的数据输出到客户端浏览器
范例:使用Response实现文件下载
1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15 * @author gacl16 * 文件下载17 */18 public class ResponseDemo02 extends HttpServlet {19 20 public void doGet(HttpServletRequest request, HttpServletResponse response)21 throws ServletException, IOException {22 downloadFileByOutputStream(response);//下载文件,通过OutputStream流23 }24 25 /**26 * 下载文件,通过OutputStream流27 * @param response28 * @throws FileNotFoundException29 * @throws IOException30 */31 private void downloadFileByOutputStream(HttpServletResponse response)32 throws FileNotFoundException, IOException {33 //1.获取要下载的文件的绝对路径34 String realPath = this.getServletContext().getRealPath("/download/1.JPG");35 //2.获取要下载的文件名36 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);37 //3.设置content-disposition响应头控制浏览器以下载的形式打开文件38 response.setHeader("content-disposition", "attachment;filename="+fileName);39 //4.获取要下载的文件输入流40 InputStream in = new FileInputStream(realPath);41 int len = 0;42 //5.创建数据缓冲区43 byte[] buffer = new byte[1024];44 //6.通过response对象获取OutputStream流45 OutputStream out = response.getOutputStream();46 //7.将FileInputStream流写入到buffer缓冲区47 while ((len = in.read(buffer)) > 0) {48 //8.使用OutputStream将缓冲区的数据输出到客户端浏览器49 out.write(buffer,0,len);50 }51 in.close();52 }53 54 public void doPost(HttpServletRequest request, HttpServletResponse response)55 throws ServletException, IOException {56 doGet(request, response);57 }58 }
运行结果如下所示:
范例:使用Response实现中文文件下载
下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。
1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15 * @author gacl16 * 文件下载17 */18 public class ResponseDemo02 extends HttpServlet {19 20 public void doGet(HttpServletRequest request, HttpServletResponse response)21 throws ServletException, IOException {22 downloadChineseFileByOutputStream(response);//下载中文文件23 }24 25 /**26 * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码27 * @param response28 * @throws FileNotFoundException29 * @throws IOException30 */31 private void downloadChineseFileByOutputStream(HttpServletResponse response)32 throws FileNotFoundException, IOException {33 String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径34 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名35 //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码36 response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));37 InputStream in = new FileInputStream(realPath);//获取文件输入流38 int len = 0;39 byte[] buffer = new byte[1024];40 OutputStream out = response.getOutputStream();41 while ((len = in.read(buffer)) > 0) {42 out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器43 }44 in.close();45 }46 47 public void doPost(HttpServletRequest request, HttpServletResponse response)48 throws ServletException, IOException {49 doGet(request, response);50 }51 }
运行结果如下所示:
文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。
范例:使用PrintWriter流下载文件
1 package gacl.response.study; 2 import java.io.FileInputStream; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.io.PrintWriter; 9 import java.net.URLEncoder;10 import javax.servlet.ServletException;11 import javax.servlet.http.HttpServlet;12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 /**15 * @author gacl16 * 文件下载17 */18 public class ResponseDemo02 extends HttpServlet {19 20 public void doGet(HttpServletRequest request, HttpServletResponse response)21 throws ServletException, IOException {22 downloadFileByPrintWriter(response);//下载文件,通过PrintWriter流23 }24 25 /**26 * 下载文件,通过PrintWriter流,虽然也能够实现下载,但是会导致数据丢失,因此不推荐使用PrintWriter流下载文件27 * @param response28 * @throws FileNotFoundException29 * @throws IOException30 */31 private void downloadFileByPrintWriter(HttpServletResponse response)32 throws FileNotFoundException, IOException {33 String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径34 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名35 //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码36 response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));37 FileReader in = new FileReader(realPath);38 int len = 0;39 char[] buffer = new char[1024];40 PrintWriter out = response.getWriter();41 while ((len = in.read(buffer)) > 0) {42 out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器43 }44 in.close();45 }46 47 public void doPost(HttpServletRequest request, HttpServletResponse response)48 throws ServletException, IOException {49 doGet(request, response);50 }51 }
运行结果如下:
正常弹出下载框,此时我们点击【保存】按钮将文件下载下来,如下所示:
可以看到,只下载了5.25MB,而这张图片的原始大小却是
这说明在下载的时候数据丢失了,所以下载不完全,所以这张图片虽然能够正常下载下来,但是却是无法打开的,因为丢失掉了部分数据,如下所示:
所以使用PrintWriter流处理字节数据,会导致数据丢失,这一点千万要注意,因此在编写下载文件功能时,要使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。
- 使用HttpServletResponse提供文件下载
- HttpServletResponse对象实现文件下载
- HttpServletResponse对象实现文件下载
- HttpServletResponse对象实现文件下载
- HttpServletResponse对象实现文件下载
- 好记性不如烂笔头13-使用HttpServletResponse实现文件下载
- 使用servlet提供下载
- 使用MFC提供的Http类下载和上传文件
- 如何使用资源文件提供Excel模板下载
- 使用MFC提供的Http类下载和上传文件
- 使用jetty做为server提供多线程文件下载
- 使用Android系统提供的DownloadManager来下载文件。
- 使用Android系统提供的DownloadManager来下载文件
- 使用JavaIO提供的API下载指定文件(image)
- servlet使用json案例,提供jar文件下载
- 使用apache作为文件服务器(仅提供文件下载,不提供路径)
- 输出硬盘文件,提供下载
- ASP.NET提供文件下载
- idea中flex与java的交互
- JNA调用C++的相关点总结
- JavaWeb基础--HttpServletResponse
- 真实经历“grub2安装错误”
- Python3.6.3 程序.exe格式打包发布
- 使用HttpServletResponse提供文件下载
- PHP目前比较常见的五大运行模式
- Java开发微信公众号
- python一个精简的ORM框架(廖老师的python教程)理解
- 23种设计模式之-----适配器模式(Adapter Pattern)
- JavaWeb基础--HttpServletRequest
- WINDOWS下django入门
- 1、jmeter配置(Error: Unable to access jarfile ApacheJMeter.jar)
- Spring学习(6)--Spring中bean的生命周期