2333~~(╯﹏╰),下载问题有好多,网上给出的方法也层次不穷,比较凌乱,参考了一下其他博主的一些资料,来写一篇比较完整的关于Struts2的文件下载。
Struts2控制文件的下载,是通过stream结果类型,该结果类型将使用文件下载作为响应。stream结果类型需要在struts.xml中进行配置,它需要指定4个属性
contentType:指定被下载文件的类型。若给出详细的类型,如:“image/jpg”。若不想给出具体的类型,则可设置参数为:“application/octet-stream”。
inputName:指定被下载文件的入口输入流(此参数内容与Action类实现下载功能类的方法名有关,参数内容应为方法去掉“get”并且第一个字母改为小写)
contentDisposition:指定下载的文件名(包括后缀)。
bufferSize:指定下载文件时的缓冲大小。
上述为Struts2文件下载的核心内容,接下来通过简单的实例发现更多的问题
1、down.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h3>文件的下载h3>
<a href="wordDownload">Word文件的下载a><br>
<a href="jpgDownload">图片的下载a>
body>
html>
一个超链接,连接的地址是一个Action的name属性,指定了该Action所处理请求的URL。
2、WordDownloadAction.java
package gzy;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class WordDownloadAction extends ActionSupport {
private String filename;//下载文件的名称
private String inputPath;//下载文件的路径
public void setInputPath(String value) {
inputPath = value;
}
public InputStream getTargetFile() throws Exception {
return ServletActionContext
.getServletContext().getResourceAsStream(inputPath);
}
public void setFilename(String filename)
throws UnsupportedEncodingException {
this.filename = new
String(filename.getBytes(), "ISO8859-1");
}
}
(1)filename与inputPath都需要在struts.xml去动态的配置,为了实现Action的复用(例如此处需要实现word文档和图片的下载)
(2)核心方法“getTargetFile()”,”TargetFile”为上述“inputName”的参数值。由该方法去获得InputStream对象
(3)关于setFilename方法,该方法是排除了在跳出保存文档时,文件名称为中文乱码的问题。
3、struts.xml
<struts>
<package name="gzy" namespace="/" extends="struts-default">
<action name="download" class="gzy.WordDownloadAction" >
<param name="filename">好.docxparam>//特意使用中文名称
<param name="inputPath">/file/好.docxparam>
<result type="stream">
<param name="contentType">application/octet-streamparam>
<param name="inputName">targetFileparam>
<param name="contentDisposition">
attachment;filename="${filename}"param>
<param name="bufferSize">4096param>
result>
action>
<action name="jpgDownload" class="gzy.WordDownloadAction" >
<param name="filename">一.jpgparam>
<param name="inputPath">/file/一.jpgparam>
<result type="stream">
<param name="contentType">image/jpgparam>
<param name="inputName">targetFileparam>
<param name="contentDisposition">
attachment;filename="${filename}"param>
<param name="bufferSize">4096param>
result>
action>
package>
struts>
(1)动态的配置了文件名和下载路径
(2)关于 attachment;filename="${filename}"
:设置了头文件信息,并且使用了表达式语言,去获得文件名
注意
1、若将attachment;filename="${filename}"
参数值改为filename=“好.docx”(意图不使用setFilename方法),则显示不出文件名(中文乱码)
2、有一位博主讲到关于stream结果类型的contentType属性:
“,将contentType参数设置为”image/jpeg”,则动作将文件发送给浏览器,并让浏览器显示其内容。将contentType参数设置为”application/octet-stream”,则动作将以文件下载的方式发送给浏览器。换一种说法就是,若为”image/jpeg”,就是告诉浏览器这是一个jpg文件,请显示它的内容;若为”application/octet-stream”,就是告诉浏览器,问用户想不想保存这个文件。”
关于这个问题,我尝试了下,打开图片并没有去显示图片,依旧是出现文件下载页面,但我把contentDisposition属性值改为filename=“1.jpg”,再次去点开链接,则发现直接显示了图片
URL改变了,为下载页面,博主查了些资料,也并未明白,若有读者明白,请告诉博主O(∩_∩)O
3、若出现
Can not find a java.io.InputStream with the name [targetFile] in the invocation stack. Check the tag specified for this action.
错误,若读者是根据上述例子,那基本是读者的inputpath的路径不对,读者可以尝试在getTargetFile()方法中,先去打印InputStream对象,若为null,这就是路径错误了(并未找到下载的文件,可参考博主上篇文章)
恩….关于路径,相对路径和绝对路径,博主还不是特别清楚,所以不说明去误导大家了,博主的file文件是放在了WebContent文件下(Eclipse环境)。