java io jar包下载_JavaWeb 之 使用 commons-io.jar 实现文件的下载

本文详细介绍了如何在JavaWeb中利用commons-io.jar进行文件下载,包括设置响应头、处理IE和谷歌浏览器的中文文件名问题,以及解决火狐浏览器的中文乱码问题。通过判断User-Agent来完美适配各种浏览器。
摘要由CSDN通过智能技术生成

一、文件下载

文件下载需要以流的传输形式进行下载。

1、流程

bba026cbd487b0594090e75c01191759.png

2、下载常用的API

response.getOutputStream(); 获取响应流

servletContext.getResourceAsStream(); 获取文件资源流

servletContext.getMimeType(); 获取文件类型

response.setContentType(); 设置响应类型

response.setHeader(); 设置响应头

注意:

需要设置响应头的值为 response.setHeader("Content-Disposition", "attachment; fileName=1.jpg")

其中 Content-Disposition 表示设置响应头,表示客户端收到数据怎么处理;

attachment 表示附件,意味着客户端收到数据是用于下载用的

fileName=文件名:fileName=后面是指定的下载的文件名

代码实现:

1 importorg.apache.commons.io.IOUtils;2

3 importjavax.servlet.ServletContext;4 importjavax.servlet.ServletException;5 importjavax.servlet.http.HttpServlet;6 importjavax.servlet.http.HttpServletRequest;7 importjavax.servlet.http.HttpServletResponse;8 importjava.io.IOException;9 importjava.io.InputStream;10 importjava.io.OutputStream;11

12

13 public class DownloadServlet extendsHttpServlet {14

15 protected void doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {16

17 //1. 获取要下载的文件名

18 String fileName = "a.jpg";19

20 //2. 获取要下载的文件类型(使用 servletContext 对象读取)

21 ServletContext servletContext =getServletContext();22 String mimeType =servletContext.getMimeType(fileName);23 System.out.println("下载的文件类型:mimeType = " +mimeType);24

25 //3. 通过响应头告诉客户端的文件类型

26 response.setContentType(mimeType);27

28 //4. 通过响应头告诉客户端是用于下载的29 //Content-Disposition 响应头,表示收到的数据怎么处理30 //attachment 表示附件,表示下载使用31 //fileName 表示指定下载的文件名

32 response.setHeader("Content-Disposition","attachment;filename=" +fileName);33

34 //5. 读取要下载的文件内容

35 InputStream inputStream = servletContext.getResourceAsStream("/upload/" +fileName);36

37 //6. 把要下载的内容回传给客户端

38 OutputStream outputStream =response.getOutputStream();39 //使用工具类读取输入流中的数据,输出到输出流中,输出给客户端

40 IOUtils.copy(inputStream, outputStream);41

42 }43 }

通过上面的代码就可以实现文件下载了,但是只能下载英文的文件,并不支持中文,这是因为在响应头中,不能包含有中文字符,只能包含 ASCII码。

乱码现象:

b9ac9f75445167b915d77bb4e98785d0.png

二、使用 URLEncoder 解决 IE和谷歌浏览器的附件的中文问题

如果客户端浏览器是 IE浏览器 或者是 谷歌浏览器,需要使用 URLEncoder 类先对中文进行 UTF 的编码操作。

因为 IE 浏览器和谷歌浏览器收到含有编码后的字符串会以 UTF-8 字符集进行解码显示。

URL编码就是把内容汉字转化为  %xx%xx 的格式(x代表十六进制的数)

示例:

1 //把中文名进行 UTF-8 编码操作。

2 String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");3 //然后把编码后的字符串设置到响应头中

4 response.setHeader("Content-Disposition", str)

注意: URLEncoder 是 java.net.URLEncoder 包中的类。

三、使用 Base64 编解码解决获取浏览器的附件的中文问题

如果客户端浏览器是火狐浏览器,那么就需要对中文名进行 BASE64 的编码。

同时还需要把请求头设置为如下格式:

请求头 Content-Disposition: attachment; filename=中文名编码成为: Content-Disposition: attachment; filename==?charset?B?xxxxx?=对上面 =?charset?B?xxxxx?= 进行说明:

=?            表示编码内容的开始

charset    表示字符集

B             表示 Base64 编码

xxxxxx     表示文件名以 Base 编码后的内容

?=            表示编码内容的结束

BASE64 解编码的实例:

1 importsun.misc.BASE64Decoder;2 importsun.misc.BASE64Encoder;3

4 importjava.io.IOException;5

6 public classBase64Test {7

8 public static void main(String[] args) throwsIOException {9 String content = "中国加油!!!";10

11 //创建一个 BASE64 的编码器

12 BASE64Encoder base64Encoder = newBASE64Encoder();13 //BASE64 的编码操作

14 String encode = base64Encoder.encode(content.getBytes("UTF-8"));15 System.out.println("Base64编码后的结果:encode = " +encode);16

17 //创建一个 BASE64 的编码器

18 BASE64Decoder base64Decoder = newBASE64Decoder();19 //BASe64 的解码操作

20 byte[] bytes =base64Decoder.decodeBuffer(encode);21 String content2 = newString(bytes);22 System.out.println("Base64解码后的结果:content2 = " +content2);23

24 }25 }

运行结果:

e3eaaf9bce87895923860e6eb28c43a3.png

因为火狐使用的是 BASE 的编解码方式还原响应中的汉字,使用 BASE64Encoder 类进行编码操作:

示例:

1 //使用下面的格式进行 BASE64 编码

2 String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";3 //设置到响应头中

4 response.setHeader("Content-Disposition", str);

四、使用请求头 User-Agent 完美解决中文乱码问题

为了解决上面两种不同编解码方式,只需要通过判断请求头中 User-Agent 这个请求头携带过来的浏览器信息即可判断是什么浏览器,然后做出不同的响应。

代码示例:

1 importorg.apache.commons.io.IOUtils;2 importsun.misc.BASE64Encoder;3

4 importjavax.servlet.ServletContext;5 importjavax.servlet.ServletException;6 importjavax.servlet.http.HttpServlet;7 importjavax.servlet.http.HttpServletRequest;8 importjavax.servlet.http.HttpServletResponse;9 importjava.io.IOException;10 importjava.io.InputStream;11 importjava.io.OutputStream;12 importjava.net.URLEncoder;13

14

15 public class DownloadServlet extendsHttpServlet {16

17 protected void doGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {18

19 //1. 获取要下载的文件名

20 String fileName = "中国.jpg";21

22 //2. 获取要下载的文件类型(使用 servletContext 对象读取)

23 ServletContext servletContext =getServletContext();24 String mimeType =servletContext.getMimeType(fileName);25 System.out.println("下载的文件类型:mimeType = " +mimeType);26

27 //3. 通过响应头告诉客户端的文件类型

28 response.setContentType(mimeType);29

30 //4. 通过响应头告诉客户端是用于下载的31 //Content-Disposition 响应头,表示收到的数据怎么处理32 //attachment 表示附件,表示下载使用33 //fileName 表示指定下载的文件名34 //response.setHeader("Content-Disposition","attachment;filename=" + fileName);35 //获取请求头进行判断

36 String header = request.getHeader("User-Agent");37 //判断是否是火狐浏览器

38 if (header.contains("Firefox")) {39

40 //使用下面的格式进行 BASE64 编码后

41 String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";42 //设置到响应头中

43 response.setHeader("Content-Disposition", str);44 } else{45

46 //把中文名进行 UTF-8 编码操作。

47 String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");48 //然后把编码后的字符串设置到响应头中

49 response.setHeader("Content-Disposition", str);50 }51

52

53 //5. 读取要下载的文件内容

54 InputStream inputStream = servletContext.getResourceAsStream("/upload/" +fileName);55

56 //6. 把要下载的内容回传给客户端

57 OutputStream outputStream =response.getOutputStream();58 //使用工具类读取输入流中的数据,输出到输出流中,输出给客户端

59 IOUtils.copy(inputStream, outputStream);60

61 }62 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值