文件下载方式:

1.超连接

2.服务器编码,通过流向客户端写回。

1.通过response设置 response.setContentType(String mimetype);

2.通过response设置 response.setHeader("Content-disposition;filename=xxx");

3.通过response获取流,将要下载的信息写出。

struts2中文件下载:

通过<result type="stream">完成。

<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>

在StreamResult类中有三个属性:

protected String contentType = "text/plain"; //用于设置下载文件的mimeType类型

protected String contentDisposition = "inline";//用于设置进行下载操作以及下载文件的名称

protected InputStream inputStream; //用于读取要下载的文件。

1、 在action类中定义一个方法:

public InputStream getInputStream() throws FileNotFoundException {

FileInputStream fis = new FileInputStream("d:/upload/" + filename);

return fis;

}

2、 在Struts.xml中配置:

<result type="stream">

<param name="contentType">text/plain</param>

<param name="contentDisposition">attachment;filename=a.txt</param>

<param name="inputStream">${inputStream}</param> 会调用当前action中的getInputStream方法。

</result>

例子:

Action:

public class DownloadFileAction extends ActionSupport{

private String filename;

public String getFilename() {

return filename;

}

public void setFilename(String filename) {

this.filename = filename;

}

public InputStream getInputStream() throws FileNotFoundException {

//解决中文乱码

filename = new String(filename.getBytes("utf-8"));

//文件从c盘下的upload文件夹中下载

FileInputStream fis = new FileInputStream("c:/upload/"+filename);

return fis;

}

@Override

public String execute() throws Exception {

System.out.println("正在下载....");

//注意:一定要返回SUCCESS,不然不会弹出下载框

return SUCCESS;

}

}

Struts.xml:

<!-- 文件下载 -->

<action name="downloadFile" class="com.demo.DownloadFileAction">

<result type="stream">

<param name="contentType">text/plain</param>

<param name="contentDisposition">attachment;filename=a.txt</param>

<!-- 调用action的getInputStream()方法 -->

<param name="inputStream"> ${inputStream}</param>


</result>

</action>

总结:Struts.xml这样的配置,会限定了下载文件的文件类型,而且也限定了下载文件的文件名称,还会出现中文名称乱码

就是下面的两个问题:

问题1:<a href="${pageContext.request.contextPath}/download?filename=捕获.png">捕获.png</a>下载报错

原因:超连接是get请求,并且下载的文件是中文名称,乱码。

问题2:下载捕获文件时,文件名称就是a.txt,下载文件后缀名是png,而我们在配置文件中规定就是txt?



解决办法:文件类型和捕获文件名都动态赋值,调用action中对应的方法赋值

<result type="stream">

<param name="contentType"> ${ contentType }</param> <!-- 调用当前action中的getContentType()方法 -->

<param name="contentDisposition"> attachment;filename=${ downloadFileName }</param>

<param name="inputStream"> ${ inputStream }</param><!-- 调用当前action中的getInputStream()方法 -->

</result>

例子:

Struts.xml:就是上面的配置

Action:

在上面的基础上加上两个方法

//获取文件mimeType类型,即contentType

public String getContentType() {

String mimeType = ServletActionContext.getServletContext().getMimeType(filename);

return mimeType;

}


//获取文件名字

public String getDownloadFileName() throws UnsupportedEncodingException {

String agent = ServletActionContext.getRequest().getHeader("user-agent");

return DownloadFileUtil.getDownloadFileName(agent, filename);

}

util:获取文件名称的文件工具类

public class DownloadFileUtil {

public static String getDownloadFileName(String agent, String filename) throws UnsupportedEncodingException {

if (agent.contains("MSIE")) {

// IE浏览器

filename = URLEncoder.encode(filename, "utf-8");

} 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;

}

}





在struts2中进行下载时,如果使用<result type="stream">它有缺陷,例如:下载点击后,取消下载,服务器端会产生异常。

在开发中,解决方案:可以下载一个struts2下载操作的插件,它解决了stream问题。