Java 之 Response 文件下载案例

文件下载需求:

1. 页面显示超链接
2. 点击超链接后弹出下载提示框
3. 完成图片文件下载

分析过程:

1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
2. 任何资源都必须弹出下载提示框
3. 使用响应头设置资源的打开方式:
   content-disposition:attachment;filename=xxx

步骤:

1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
2. 定义Servlet
	1. 获取文件名称
	2. 使用字节输入流加载文件进内存
	3. 指定response的响应头: content-disposition:attachment;filename=xxx
	4. 将数据写出到response输出流

  

代码实现:

  下载页面:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>文件下载</title>
 6 </head>
 7 <body>
 8
 9
10     <a href="/day13/img/狐狸.jpg">图片1</a>
11
12     <a href="/day13/img/2.jpg">图片2</a>
13
14     <a href="/day13/img/1.avi">视频</a>
15     <hr>
16
17
18     <a href="/day13/downloadservlet?filename=狐狸.jpg">图片1</a>
19
20     <a href="/day13/downloadservlet?filename=2.jpg">图片2</a>
21
22     <a href="/day13/downloadservlet?filename=1.avi">视频</a>
23
24
25
26
27 </body>
28 </html>

  DownLoadServlet 类

 1 import javax.servlet.ServletContext;
 2 import javax.servlet.ServletException;
 3 import javax.servlet.ServletOutputStream;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.FileInputStream;
 9 import java.io.IOException;
10
11 @WebServlet("/downloadservlet")
12 public class downloadservlet extends HttpServlet {
13     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         //1获取请求参数,文件名称
15         String filename = request.getParameter("filename");
16
17         //2使用字节输入流加载文件进内存
18         // 2.1 找文件服务器路径
19         ServletContext servletContext = this.getServletContext();
20         String realPath = servletContext.getRealPath("/img/" + filename);
21
22         //2.2 使用字节流关联
23         FileInputStream fis = new FileInputStream(realPath);
24
25         //3 设置 response 的响应头
26         // 3.1 设置响应头类型:content-type
27         String mimeType = servletContext.getMimeType(filename);
28         response.setHeader("content-type",mimeType);
29         // 3.2 设置响应头打开方式:content-disposition
30
31         response.setHeader("content-disposition","attachment;filename="+filename);
32
33
34         // 4. 将输入流的数据写出到输出流中
35         ServletOutputStream sos = response.getOutputStream();
36
37         byte[] buff = new byte[1024*8];
38         int len = 0;
39
40         while((len = fis.read(buff)) != -1) {
41             sos.write(buff,0,buff.length);
42         }
43
44         // 关闭流对象
45         fis.close();
46     }
47
48     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
49         this.doPost(request, response);
50     }
51 }

  上面的案例中发现,当下载的文件名字是中文的时候,下载的时候会出现乱码。

文件名中文乱码问题

  解决思路:

    (1)获取客户端使用的浏览器版本信息

    (2)根据不同的版本信息,设置 filename 的编码方式不同

  编码工具类:

  使用 Base64 编码,需要导入 commons-codec-1.13.jar 包。

 1 package cn.itcast.download;
 2
 3
 4 import org.apache.commons.codec.binary.Base64;
 5
 6 import java.io.UnsupportedEncodingException;
 7 import java.net.URLEncoder;
 8
 9
10 public class DownLoadUtils {
11
12     public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
13         if (agent.contains("MSIE")) {
14             // IE浏览器
15             filename = URLEncoder.encode(filename, "utf-8");
16             filename = filename.replace("+", " ");
17         } else if (agent.contains("Firefox")) {
18             Base64 base64Encoder = new Base64();
19             // 火狐浏览器
20             //BASE64Encoder base64Encoder = new BASE64Encoder();
21             filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
22         } else {
23             // 其它浏览器
24             filename = URLEncoder.encode(filename, "utf-8");
25         }
26         return filename;
27     }
28 }

  DownLoadServlet 类(改进):

 1 package cn.itcast.download;
 2
 3 import javax.servlet.ServletContext;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.ServletOutputStream;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import java.io.FileInputStream;
11 import java.io.IOException;
12
13 @WebServlet("/downloadservlet")
14 public class downloadservlet extends HttpServlet {
15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
16         //1获取请求参数,文件名称
17         String filename = request.getParameter("filename");
18
19         //2使用字节输入流加载文件进内存
20         // 2.1 找文件服务器路径
21         ServletContext servletContext = this.getServletContext();
22         String realPath = servletContext.getRealPath("/img/" + filename);
23
24         //2.2 使用字节流关联
25         FileInputStream fis = new FileInputStream(realPath);
26
27         //3 设置 response 的响应头
28         // 3.1 设置响应头类型:content-type
29         String mimeType = servletContext.getMimeType(filename);
30         response.setHeader("content-type",mimeType);
31         // 3.2 设置响应头打开方式:content-disposition
32
33         // 3.3 解决中文文件名问题
34           // 1 获取 user-agent 请求头
35         String agent = request.getHeader("user-agent");
36         // 2 使用工具类方法编码文件即可
37         filename = DownLoadUtils.getFileName(agent, filename);
38
39         response.setHeader("content-disposition","attachment;filename="+filename);
40
41
42         // 4. 将输入流的数据写出到输出流中
43         ServletOutputStream sos = response.getOutputStream();
44
45         byte[] buff = new byte[1024*8];
46         int len = 0;
47
48         while((len = fis.read(buff)) != -1) {
49             sos.write(buff,0,buff.length);
50         }
51
52         // 关闭流对象
53         fis.close();
54     }
55
56     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
57         this.doPost(request, response);
58     }
59 }

原文地址:https://www.cnblogs.com/niujifei/p/11621866.html

时间: 2024-11-05 16:20:55

Java 之 Response 文件下载案例的相关文章

Java中都通用文件下载(ContentType、文件头、response、out四步骤)

Java中都通用文件下载(ContentType.文件头.response.out四步骤) 新浪微博:IT国子监(记得关注噢) http://weibo.com/itguozijian   我们就直接切入主题啦,文件下载只需要四步: 1.设置文件ContentType类型 2.设置文件头 3.通过response获取ServletOutputStream对象(out) 4.写到输出流(out)中 下载代码: 这里我使用的是SpringMVC,不过它在这里的唯一用途就是用来获取ServletCon

java—servlet实现文件下载功能

最近在学javaweb技术,利用所学知识做了一个简单的项目,在服务器上实现给用户下载文件的功能.自动列出文件夹下的文件提供下载,支持中文文件名. 结果图 其中使用了tomcat来部署服务器,代码中应用了少许EL表达式和JSTL标签,使用了jsp和servlet,当然还有java和http的基础知识,但是个人觉得重点是http的Content-Disposition头信息和Content-type头信息在servlet中下载方面的应用,详见DownloadPageServlet.java源码. 关

java输出流实现文件下载

//导出Excel try { HSSFWorkbook wb = carService.export(list); //调用service方法~! response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=carsList.xls"); OutputStream ouput

java实现大文件下载(http方式)

java实现大文件下载,基于http方式,控件神马的就不说了. 思路:下载文件无非要读取文件然后写文件,主要这两个步骤,主要难点: 1.读文件,就是硬盘到内存的过程,由于jdk内存限制,不能读的太大. 2.写文件,就是响应到浏览器端的过程,http协议是短链接,如果写文件太慢,时间过久,会造成浏览器死掉. 知识点: 1.org.apache.http.impl.client.CloseableHttpClient  模拟httpClient客户端发送http请求,可以控制到请求文件的字节位置.

Response验证码案例 January 27,2020

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>验证码点击切换</title> <script> /* 分析: 点击超链接或者图片,需要换一张 1.给超链接和图片绑定单击事件 2.重新设置图片的src属性值 */ window.onload=function () {//加载完毕后 var i

Java 实现多线程文件下载(HTTP)

实现原理: 用httpConnection.setRequestProperty("RANGE", "bytes= xxx-xxx");获取指定的数据块 用RandomAccessFile实现文件随机访问,写入指定数据块到文件. 关键事项:获取远程文件大小,根据文件大小确定下载线程个数(可固定线程数,也可固定每个线程下载数据块大小,用户自己决定). package org.hundred.multithreads; import java.io.File; impo

java中一个memcached案例

下面先来一个网络上的案例,这个案例比较简单,直接在类中进行一些参数的配置,具体代码如下: package com.wzpmt; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; public class MemCachedManager

java实现ftp文件下载的源代码

这几天做的一个项目中用到了ftp文件传输,用java实现了ftp文件的下载. 一.win7下搭建ftp服务器 详见:http://jingyan.baidu.com/article/4b52d7026f50eefc5c774bcc.html 二.用java实现ftp文件下载 使用org.apache.commons.net  jar包,下载地址:http://commons.apache.org/proper/commons-net/download_net.cgi 下载完成后,新建java工程

JAVA Excel API学习案例

先贴代码吧,运行一下,看看效果,然后看看注释,再看看代码后面的基础介绍 创建一个新excel并写入数据: public static void myExcel2() throws IOException, WriteException { WritableWorkbook wwb = Workbook.createWorkbook(new File("F:" + File.separator + "myExcel1.xls")); // 创建excel表格中的一个s