java struts 文件下载_关于Struts2的文件下载

首先先来说下关于文件下载的原理:

服务端为客户端提供了一个下载服务,所以服务端需要一个输出流(把客户请求下载的文件输出),相对于服务端来说,客户端需要下载接收一个文件,所以它需要一个输入流(接收文件)。

服务器读取要下载文件的内容,用一个Response响应流写回并设置HTTP头信息ContentType(文件类型)、 ContentDisposition(以什么方式打开)

下面给出一个小Demo,具体代码具体分析吧

1、首先是提供下载的页面:download.jsp

给出超链接到Action并用Get方式传递一个文件名进行属性注入

1

2

3

4

5

6

下载文件示例

7

8

9

下载文件

10 点击下载照片文件

11 点击下载压缩包文件

12 点击下载文本文件

13

14

2、处理下载文件的Action:DowloadAction.java

这里提供了一个成员变量属性来接收页面传递过来的文件名,由于文件名是以Get方式传递过来的,中文会出现乱码问题,所以在setter方法里需要做一些处理,也就是重新编码。

1 packagecom.lcw.struts2.dowload;2

3 importjava.io.File;4 importjava.io.FileInputStream;5 importjava.io.FileNotFoundException;6 importjava.io.IOException;7 importjava.io.InputStream;8 importjava.io.UnsupportedEncodingException;9 importjava.net.URLEncoder;10

11 importorg.apache.struts2.ServletActionContext;12

13 importsun.misc.BASE64Encoder;14

15 importcom.opensymphony.xwork2.ActionSupport;16 /**

17 * 对于客户端来说它需要下载接收一个文件,也就是说它需要一个输入流18 * 对于服务端来说它需要对外提供一个下载的服务,也就是说它需要一个输出流19 */

20

21 public class DowloadAction extendsActionSupport {22

23 private String filename;//下载页面传递了该参数,需提供setter方法接收

24

25 public voidsetFilename(String filename) {26 //由于是get方式传递的,中文会出现乱码,不能直接获取,需转码

27 try{28 this.filename = new String(filename.getBytes("ISO-8859-1"),"utf-8");29 } catch(UnsupportedEncodingException e) {30 e.printStackTrace();31 }32 }33

34 publicString execute(){35 System.out.println("正在下载文件:"+filename);36 returnSUCCESS;37 }38

39 //为客户端提供输入流

40 public InputStream getInputStream() throwsFileNotFoundException{41 String srcFile=ServletActionContext.getServletContext().getRealPath("/download")+"/"+filename;42 File file=new File(srcFile);//得到一个file对象

43 return new FileInputStream(file);//返回一个文件输入流

44 }45

46 //根据不同的文件动态给出MIME文件类型

47 publicString getContentType(){48 //在Tomcat Conf里的web.xml有对应的映射文件

49 returnServletActionContext.getServletContext().getMimeType(filename);50 }51

52 //返回一个文件名

53 public String getFilename() throwsIOException{54 String agent=ServletActionContext.getRequest().getHeader("user-agent");//根据http头信息获取对应的浏览器类型

55 returnencodeDownloadFilename(filename,agent);56 }57

58

59 //下载附件名乱码问题 , IE和火狐 解决不同 IE默认是Url编码 火狐默认是base64编码

60 publicString encodeDownloadFilename(String filename, String agent)61 throwsIOException {62 if (agent.contains("Firefox")) { //火狐浏览器

63 filename = "=?UTF-8?B?"

64 + new BASE64Encoder().encode(filename.getBytes("utf-8"))65 + "?=";66 } else { //IE及其他浏览器

67 filename = URLEncoder.encode(filename, "utf-8");68 }69 returnfilename;70 }71 }

看了上面的代码,如果不清楚这块知识点的朋友可能会有点蒙,别急,下面我来解析下这段代码是怎么来的

首先Struts2的文件下载是通过一个结果集stream来完成的,在Struts2核心包里的struts-default.xml里我们可以找到这样的一句话:

我们来看下这个类(org.apache.struts2.dispatcher.StreamResult)里面有什么,Ctrl+Shift+T关联下源代码

99309ce6fc3e76f0328b789a20d2cdad.png

这个类里面给出了很多参数,因为都有默认值,所以我们不需要全部到去改动它,只需要改变我们需要的地方就可以了。

这里来解释下上面画红色框的参数内容:contentType,contentDisposition,inputName

contetType:是下载文件对应的MIME协议类型,比如:text/html,text/plain等,这个参数我们不能写死,因为我们的下载文件的类型有很多,有时是图片,有时是文档等。

contentDisposition:是下载文件的打开方式,这里默认是inline也就是内联在浏览器打开,如果不想关联浏览器我们可以把它设置成attment以附件的形式打开。

inputNmae:这是定义一个返回流(客户端需要的输入流)的名称,属性值为inputStream。

所以我们需要在Action里面提供这些东西,利用JAVA的反射机制让Struts2的配置文件(压入值栈,并给出getter方法)读取到就行了。

这里我们的下载附件名依旧会乱码,因为IE等浏览器默认的编码是URL而火狐浏览器默认的编码是BASE64,我们需要在这里判断客户端使用的是什么浏览器,这个很简单,只需要得到客户端的HTTP头信息Agment就行了,具体代码在上面encodeDownloadFilename方法里以给出,拿来用便是了。

3、再来看下配置文件struts.xml的配置:

由于Action里已给出我们所需参数的getter方法,我们在这边这需要用Ognl表达式取出,就可以根据我们要下载的文件,动态给出所需参数了,没有设置的参数就意味着保持默认值。

1 <?xml version="1.0" encoding="UTF-8"?>

2 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"4 "http://struts.apache.org/dtds/struts-2.0.dtd">

5

6

7

8

9

10

11

12

13

14

15

16

17 ${contentType}

18

19

20 attachment;filename=${filename}

21

22

23

24

25

然后我们新建一个文件夹download,把要下载的文件和web页面提供的文件名一样放入

9bcff6d09ec45ecc17494c199a0f08de.png

到这里就大功告成了,看下页面效果吧:

bc14a5812f5ce349303fd78905964458.png

6832da4556036cc1fb7b2fac1db9b96a.png

f40b99aab7e3c771e45916a86258968f.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值