首先搭建好struts2 框架,导入相应的jar包,配置web.xml
1、将commons-fileupload jar包 commons-io jar包导入
2、设计上传页面
设计一个表单,设置表单enctype="multipart/form-data",以数据流形式传递
<form action="uploadfile.action" method="post" enctype="multipart/form-data" theme="simple"> <!-- html 控件上传 --> <table align="center"> <tr> <td> 选择文件 </td> <td> <input type="file" name="myfile"> </td> <td> <font color="red">*</font>最大可上传10M,请注意上传文件大小 </td> </tr> <tr> <td> </td> <td align="right"> <input type="submit" value=" 提交 "> </td> <td> </td> </tr> </table> <!-- s标签 控件上传 <s:file name="myfile" label=""></s:file><br/> <!--自定义上传控件样式 --> <input type="file" name="myfile" style="display: none;" onchange="ye.value=value"> <input name="ye"> <input type=button value="浏览..." onclick=myfile.click() > <input type=button value="Browse..." onclick=myfile.click() style="display: none;"> --> </form>
以上展示了三种方式实现样式,界面都异曲同工。
3、实现文件上传的action
public class upload extends ActionSupport{ /** * */ private static final long serialVersionUID = 1L; private File myfile; //获取文件信息 private String myfileFileName; //获取文件名 private String myfileContentType; //获取文件类型 public File getMyfile() { return myfile; } public void setMyfile(File myfile) { this.myfile = myfile; } public String getMyfileFileName() { return myfileFileName; } public void setMyfileFileName(String myfileFileName) { this.myfileFileName = myfileFileName; } public String getMyfileContentType() { return myfileContentType; } public void setMyfileContentType(String myfileContentType) { this.myfileContentType = myfileContentType; } @Override public String execute() throws Exception { // TODO Auto-generated method stub System.out.println("上传文件的真实文件名:"+myfileFileName); System.out.println("上传文件的类型:"+myfileContentType); System.out.println("文件的临时文件名"+myfile.getName()); //把上传过来的文件存放到e盘temp目录下,以真实的文件名作为名字 OutputStream output = null; InputStream input = null; try { output = new FileOutputStream("e:/temp/" + myfileFileName); //建立一个1k大小的缓冲区 byte[] bs = new byte[1024]; input = new FileInputStream(myfile); int length= 0; //length=input.read(bs)这句话中,length=-1代表了读到文件结尾 while((length=input.read(bs)) > 0) { output.write(bs,0,length); } } finally { input.close(); output.close(); } return SUCCESS; } }
比较重要的知识点
private File myfile; //获取文件内容信息
private String myfileFileName; //获取真实文件名
private String myfileContentType; //获取文件类型
Struts2支持用更多的属性来获取有关上传文件的真实文件名和文件类型。
比如:表单中包含了一个叫xyz的文件域,也就是类似于<input type=”file” name=”xyz”,那么可以用三个属性来获取上传文件的信息:
将处理上传文件的Action类修改一下,添加两个属性:myfileFileName和myfileContentType,以及他们对应的getter/setter方法,来尝试获得文件的真实文件名和文件类型。
另外,保存文件的时候,也使用文件的真实名称。
4、映射上面的action
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <!-- struts.devMode struts的开发模式,默认为false,true,修改该文件会自动加载,不用重新启动tomcat服务器 --> <constant name="struts.devMode" value="false" /> <constant name="struts.multipart.saveDir" value="/tmp" /> <include file="upload.xml" /> </struts>
设置开发模式为true出错了,后来改成false,程序就对了,这个还不知道为什么?
upload.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <!-- 设置文件的最大值 --> <constant name="struts.multipart.maxSize" value="10000000" /> <package name="test" extends="struts-default"> <action name="uploadfile" class="com.etc.action.upload"> <!-- 限制文件大小 --> <!-- <interceptor-ref name="fileUpload"> <param name="allowedTypes">text/plain</param> <param name="maximumSize">1000000000</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> --> <result name="success" type="dispatcher">/welcome.jsp</result> <result name="input">/uploadfile.jsp</result> </action> </package> </struts>
经过以上步骤,一个struts2的上传功能就实现了。
以下几点补充
1.限制文件的大小及类型
在文件上传的时候,有可能需要对文件的大小和类型做出限制。Struts2支持直接在fileUpload拦截器上设置参数来进行限制。
在引用fileUpload拦截器的时候,可以指定三个参数(指定<param>子元素):
如果上传的文件不满足以上的参数指定的条件,则会跳转到一个叫input的<result>上,一般input都会指回到提交之前的页面,也就是文件上传页面。
参数非常简单,但是配置比较怪异,fileUpload拦截器虽然在defaultStack拦截器栈上已经引用了,但是还可以在defaultStack拦截器栈之前再引用一次,然后在这次引用上指定参数,代码如上action配置中。
2.上传超大的文件
Struts2在实现文件上传的时候,还有一个小问题,那就是默认上传文件的大小是不能超过2097152字节的。这个配置在struts2-core-2.1.8.1.jar文件里面,“\org\apache\struts2”文件夹下的default.properties文件里面,配置:struts.multipart.maxSize=2097152
有两种方法更改默认大小,来覆盖默认配置
一种是在Struts.properties里面配置,另外一种就是在struts.xml里面配置。
这里以struts.xml中的配置为例:
<constant name="struts.multipart.maxSize" value="10000000" />
3.在一个表单中上传多个文件
只需要在提交页面上添加同名的多个文件输入域,然后在Action中对应使用File类型的数组去接收这些参数即可。
页面代码:
<form action="uploadMore.action" method="post" enctype="multipart/form-data"> 文件: <input type="file" name="myfile"> <br> 文件: <input type="file" name="myfile"> <br> 文件: <input type="file" name="myfile"> <br> 文件: <input type="file" name="myfile"> <br> <input type="submit" value="提交"> </form>action代码:
public class uploadMore extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private File[] myfile; // 获取文件信息 private String[] myfileFileName; // 获取文件名 private String myfileContentType; // 获取文件类型 public File[] getMyfile() { return myfile; } public void setMyfile(File[] myfile) { this.myfile = myfile; } public String[] getMyfileFileName() { return myfileFileName; } public void setMyfileFileName(String[] myfileFileName) { this.myfileFileName = myfileFileName; } public String getMyfileContentType() { return myfileContentType; } public void setMyfileContentType(String myfileContentType) { this.myfileContentType = myfileContentType; } @Override public String execute() throws Exception { // TODO Auto-generated method stub // 把上传过来的文件存放到e盘temp目录下,以真实的文件名作为名字 OutputStream output = null; InputStream input = null; try { for (int i = 0; i < myfileFileName.length; i++) { output = new FileOutputStream("e:/temp/" + myfileFileName[i]); // 建立一个1k大小的缓冲区 byte[] bs = new byte[1024]; input = new FileInputStream(myfile[i]); int length = 0; // length=input.read(bs)这句话中,length=-1代表了读到文件结尾 while ((length = input.read(bs)) > 0) { output.write(bs, 0, length); } } } finally { input.close(); output.close(); } return SUCCESS; } }
upload.xml 配置
<action name="uploadMore" class="com.etc.action.uploadMore"> <result name="success" type="dispatcher">/welcome.jsp</result> <result name="input">/uploadfile.jsp</result> </action>
这样多个文件上传基本成功了,主要注意上传文件大小和类型和程序设置的相匹配。
还有一点补充
<constant name="struts.multipart.saveDir" value="/tmp" />
这个是设置上传文件的临时存储文件信息的文件夹,假如在该目录下,没有该文件夹,程序会自动创建。
struts2的文件上传先到这里,后续在补充下载的,本文主要引用了http://sishuok.com/forum/blogPost/list/4121.html,然后自己边敲边看的。这里面讲的比较详细,我把重点给总结了下。建议和我一样的初学者,可以看看研磨struts2这本电子书,挺不错的!