这是一个关于struts2的文件下载和上传功能案例,只是简单的实现功能,并无复杂的处理,如重名、文件名不能含特殊字符等。
1.web.xml配置
<filter>
<!-- 配置struts核心过滤器 -->
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.上传页面index.jsp
<form action="${pageContext.request.contextPath }/fileUpload" method="post" enctype="multipart/form-data">
上传文件:<input type="file" name="file1"/><br/>
<input type="submit" value="上传"/>
</form></span>
3.上传的Action代码
public class FileUploadAction extends ActionSupport{
private File file1;//上传的文件(字段名与表单元素名一致,自动封装)
private String file1FileName;//上传文件的文件名
private String file1ContentType;//上传文件的类型
//给字段set方法
public void setFile1(File file1) {
this.file1 = file1;
}
public void setFile1FileName(String file1FileName) {
this.file1FileName = file1FileName;
}
public void setFile1ContentType(String file1ContentType) {
this.file1ContentType = file1ContentType;
}
@Override
public String execute() throws Exception {
//获取上传目录路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//创建上传的文件对象
File file = new File(path,file1FileName);
//调用工具类的方法上传文件
/*
* 第一个参数:上传的原文件
* 第二个参数:上传的目录文件
*/
FileUtils.copyFile(file1, file);
return super.execute();
}
}
4.下载的Action代码
public class FileDownAction extends ActionSupport{
private String path;
/**
* 获取文件列表
* @return
*/
public String list(){
//获取上传的文件目录路径
path = ServletActionContext.getServletContext().getRealPath("/upload");
//创建目录对象
File file = new File(path);
//获取目录中所有的文件
String fileNames[] = file.list();
//将文件名保存到域对象
ActionContext.getContext().getContextMap().put("files", fileNames);
return "files";
}
/**
* 保存下载的文件名
*/
private String fileName;
public void setFileName(String name) {
try {
//处理中文编码
name = new String(name.getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = name;
}
/**
* 下载
* @return
*/
public String down(){
return "down";
}
/**
* 获取流,与配置文件的流对应
* @return
*/
public InputStream getMyStream(){
InputStream asStream = ServletActionContext.getServletContext().getResourceAsStream("/upload/"+this.fileName);
return asStream;
}
/**
* 下载显示的文件名
* 与配置文件总的名称对应
* @return
*/
public String getDownFileName(){
try {
return URLEncoder.encode(this.fileName,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
5.struts配置文件struts.xml
<struts>
<!-- 配置上传大小限制:10M -->
<constant name="struts.multipart.maxSize" value="10485760"></constant>
<package name="upload_down" abstract="false" extends="struts-default">
<global-results>
<!-- 当上传/下载失败时候,struts会捕获错误 -->
<result name="input">/message.jsp</result>
</global-results>
<!-- 配置upload Action -->
<action name="fileUpload" class="cn.app.action.FileUploadAction">
<interceptor-ref name="defaultStack">
<!-- 限制上传文件的类型 -->
<!-- <param name="fileUpload.allowedExtensions">txt,png</param>-->
</interceptor-ref>
<result name="success" type="dispatcher">/down_list</result>
</action>
<!-- 配置down Action -->
<action name="down_*" class="cn.app.action.FileDownAction" method="{1}">
<result name="files">/list.jsp</result>
<!-- 下载结果处理,返回"stream" -->
<result name="down" type="stream">
<!-- 设置下载的返回类,设置为二进制,即所有的类型都可以下载 -->
<param name="contentType">application/octet-stream</param>
<!-- 设置下载时用到的流,对应Action里的流的属性 -->
<param name="inputName">myStream</param>
<!-- 下载显示的文件名称 -->
<param name="contentDisposition">attachment;fileName=${downFileName}</param>
<!-- 设置缓冲区大小 -->
<param name="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
6.下载文件列表jsp
<%@taglib uri="/struts-tags" prefix="s" %>
<table border="1" cellspacing="0">
<tr>
<th></th>
<th>文件名</th>
<th>下载</th>
</tr>
<s:iterator var="file" value="#files" status="s">
<tr>
<td><s:property value="#s.count"/></td>
<td><s:property value="#file"/></td>
<td><s:a href="down_down?fileName=%{#file}">下载</s:a></td>
</tr>
</s:iterator>
</table >
7.期间遇到了一点小问题,跟大家分享一下,是一个非常低级的错误
警告: Error setting expression 'file1' with value '[Ljava.lang.String;@2fc5809e'
ognl.MethodFailedException: Method "setFile1" failed for object cn.app.action.FileUploadAction@4ab4faeb [java.lang.NoSuchMethodException: cn.app.action.FileUploadAction.setFile1([Ljava.lang.String;)]
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1289)
at ognl.OgnlRuntime.setMethodValue(OgnlRuntime.java:1478)
...部分
错误源头
<form action="${pageContext.request.contextPath }/fileUpload" method="post" enctype="multipart/form-data">
</span>上传用户:<input type="text" name="userName"/><br/>
</span>上传文件:<input type="file" name="file1"/><br/>
<input type="submit" value="上传"/>
</form>
这是正确的代码,而我的错误是 form 标签的 enctype 属性值错了,我写成了 "mutipart/form-data",少了个 l ,这是一个非常低级的错误。
一开始没注意,一直都以为是 form 表单里的元素有问题,其实不然。
*新手代码,如有不足请多多指教,谢谢!
*博客新手,还不太会编辑器的功能,所以排版不好。