-----------------------------单个文件上传-------------------------------
(1)上传页面:testFileUpload2.jsp
<form action="actions/upload2" method="post" enctype="multipart/form-data"> 上传文件:<input type="file" name="myfile" ><br> <input type="submit" value="ok"> </form>
注意form属性要加上enctype="multipart/form-data"。
上传成功页面:uploadOK.jsp(以下均相同):
上传成功!
(2)提交的Action: UploadAction2
package action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import com.opensymphony.xwork2.ActionSupport; public class UploadAction2 extends ActionSupport { private File myfile;////上传的文件 private String myfileFileName;//上传的文件名 private String myfileContentType;//上传的文件类型
//省略getter、setter
@Override public String execute() throws Exception { System.out.println("上传的文件:"+myfile); System.out.println("上传的真实文件名: "+myfileFileName); System.out.println("文件类型:"+myfileContentType); InputStream is = null; OutputStream os = null; //假如要把上传的文件放到e:/temp File file = new File("e:/temp"); //如果e盘下不存在temp就创建目录 if(!file.exists()) { file.mkdirs(); } //以文件的真实名称保存 file = new File(file,myfileFileName); try { //读取上传的文件 is = new FileInputStream(myfile); //建立一个1k大小的缓冲区 byte[] b = new byte[1024]; //把上传的文件输出到os中 os = new FileOutputStream(file); int len = 0; //len=-1表示读到文件结尾 while((len = is.read(b))>0) { os.write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); }finally{ is.close(); os.close(); } return super.execute(); } }
(3)struts.xml的配置
<package name="test" namespace="/actions" extends="struts-default"> <action name="upload2" class="action.UploadAction2"> <interceptor-ref name="fileUpload"> <param name="allowedTypes">text/plain</param> <param name="maximumSize">10000</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> <result name="input">/testFileUpload2.jsp</result> <result>/uploadOK.jsp</result> </action> </package>
在文件上传的时候,有可能需要对文件的大小和类型做出限制。Struts2支持直接在fileUpload拦截器上设置参数来进行限制。
在引用fileUpload拦截器的时候,可以指定三个参数(指定<param>子元素):
allowedTypes:指定允许上传的文件的类型,如果存在多种类型,以逗号隔开。如果不知道某种文件的ContentType可以先上传一下试试,在后台输出ContentType来。
maximumSize:指定允许上传的文件的最大字节数。
allowedExtensions:指定允许上传的文件的扩展名。
如果上传的文件不满足以上的参数指定的条件,则会跳转到一个叫input的<result>上,一般input都会指回到提交之前的页面,也就是文件上传页面。
可以在提交页面的合适的地方加上<s:fielderror/>来显示错误信息,经本人测试,struts上传文件时是先检查文件大小再检查文件类型,所以如过上传的非txt类型文件(比如*.html)超过1000字节的话是”报文件太大”的错误,只需要把最大字节数改大超过html文件,报告上传类型错误便可解决。
(4)运行结果
注意上传时文件要确保存在!
Struts2在实现文件上传的时候,还有一个小问题,那就是默认上传文件的大小是不能超过2097152字节的。注意:上传的文件首先要存在,否则会抛异常。
解决办法之一:在struts.xml加入如下的常量定义:
<constant name="struts.multipart.maxSize" value="10000000" />
这里设置上传文件的最大值为大约10M。
当上传的时候,控制台上出现:Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir时,可以在struts.xml中添加如下配置解决:
<constant name="struts.multipart.saveDir" value="/tmp"/>
------------------------------多个文件上传------------------------------
只需要在提交页面上添加同名的多个文件输入域,然后在Action中对应使用File类型的数组去接收这些参数即可
(1)上传页面:testMutiFileUpload.jsp
<form action="actions/mutiupload" 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="submit" value="ok"> </form>
注意name属性值是一样的
(2)提交的action:MutiUploadAction。
package action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import com.opensymphony.xwork2.ActionSupport; public class MutiUploadAction extends ActionSupport { File[] myFile;//上传的文件 String[] myFileFileName;//上传的文件名 String[] myFileContentType;//上传的文件类型 //省略getter、setterpublic void setMyFileContentType(String[] myFileContentType) { this.myFileContentType = myFileContentType; } @Override public String execute() throws Exception { InputStream is = null; OutputStream os =null; //afile存放上传的文件名,注意初始化数组 File[] afile = new File[myFileFileName.length]; File file = new File("e:/temp"); if(!file.exists()) { file.mkdirs(); } for(int i=0;i<myFileFileName.length;i++) { //依次输出上传的文件类型 System.out.println("上传文件的类型:"+myFileContentType[i]); try { //把上传的文件名依次存到aFile数组 afile[i] = new File(file,myFileFileName[i]); ////将上传过来的文件输出到os中,以真实的文件名作为名字 os = new FileOutputStream(afile[i]); //依次读取上传的文件 is = new FileInputStream(myFile[i]); byte[] b = new byte[1024]; int len = 0; while((len=is.read(b))>0) { os.write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); }finally{ is.close(); os.close(); } } return super.execute(); } }
(3)struts.xml的配置
<package name="test" namespace="/actions" extends="struts-default"> <action name="mutiupload" class="action.MutiUploadAction"> <result> /uploadOK.jsp </result> </action> </package>
(4)运行结果
后台打印:
------------------------------文件下载 ---------------------------------------
会用到struts的stream类型的Result, Result会返回一个InputStream,只需要让这个InputStream能读到用户想要下载的文件即可。
(1)文件下载jsp页面:testFileDownload.jsp
<h2><a href="actions/download">文件下载</a></h2>
(2)实现下载的action
package action; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import com.opensymphony.xwork2.ActionSupport; public class DownloadAction extends ActionSupport { public String getDownloadFileName() { String name = ""; try { name = new String("测试".getBytes(),"ISO8859-1"); } catch (Exception e) { e.printStackTrace(); } return name+".txt"; } public InputStream getInputStream() throws FileNotFoundException { File file = new File("e:/temp/test.txt"); return new FileInputStream(file); } }
注意:E:/temp下要存在test.txt,否则会抛异常。
动态地设置默认的下载名时,如果是英文的文件名就不需要做上面的编码转换,可直接返回字符串。
(3)struts.xml的配置
<package name="test" namespace="/actions" extends="struts-default"> <action name="download" class="action.DownloadAction"> <result type="stream"> <param name="contentDisposition">attachment;filename=${downloadFileName}</param> </result> </action> </package>
contentType:下载文件的类型。stream类型的结果共可以指定7个参数:
contentLength:下载文件的长度,用于浏览器的进度条显示。
contentDisposition:指定文件下载的默认名字,如果不指定则使用Action名.action。
inputName:Action中用于返回InputStream的get方法的名字,默认为inputStream,因此,我们的Action中定义了getInputStream的方法。
bufferSize:缓冲区大小,默认为1k。
allowCaching:是否允许浏览器进行缓存。
contentCharSet:HTTP响应头信息中的编码方式。
在以上7个参数中,最常用的是使用contentDisposition来指定默认的文件下载名,其他的使用默认即可