作者通过一个文件批量上传和动态下载的WEB项目来讲解struts2的文件上传和下载是如何实现,以及注意事项。开门见山,直接开始。
目录结构:
文件上传:
fileupload.jsp(上传页面):
1 <body> 2 <s:form action="upload" method="post" enctype="multipart/form-data"> 3 <s:file label="选择文件" name="myImg"></s:file> 4 <br/> 5 <s:file label="选择文件" name="myImg"></s:file> 6 <br/> 7 <s:file label="选择文件" name="myImg"></s:file> 8 <br/> 9 <s:file label="选择文件" name="myImg"></s:file> 10 <br/> 11 12 <s:submit value="提交"></s:submit> 13 </s:form> 14 </body>
这里实现批量上传,关键点在第二行的method="post" 和 enctype="multipart/form-data", 批量上传只要将多个<s:file/>标签的名字设置为一致就可以了,和单个上传类似。
UploadAction.java(处理上传文件的action):
1 package com.sunflower.upload; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.io.OutputStream; 11 12 import org.apache.struts2.ServletActionContext; 13 14 import com.opensymphony.xwork2.ActionSupport; 15 16 /** 17 * @author hanyuan 18 * @time 2012-7-7 下午03:03:21 19 */ 20 public class UploadAction extends ActionSupport { 21 /** 将缓存控件设置为1M */ 22 public static int BUFFER_SIZE = 1024 * 1024; 23 /** 上传的文件 */ 24 private File[] myImg; 25 // /** 文件的标题 */ 26 // private String caption; 27 private String[] myImgFileName; 28 private String[] myImgContentType; 29 30 // 31 // /** 得到文件扩展名并且生成自定义文件名 */ 32 // public String getWholeName(String fileName) { 33 // int index = fileName.lastIndexOf("."); 34 // fileName = this.caption + fileName.substring(index); 35 // return fileName; 36 // } 37 38 public static int getBUFFER_SIZE() { 39 return BUFFER_SIZE; 40 } 41 42 public static void setBUFFER_SIZE(int bUFFERSIZE) { 43 BUFFER_SIZE = bUFFERSIZE; 44 } 45 46 public File[] getMyImg() { 47 return myImg; 48 } 49 50 public void setMyImg(File[] myImg) { 51 this.myImg = myImg; 52 } 53 54 public String[] getMyImgFileName() { 55 return myImgFileName; 56 } 57 58 public void setMyImgFileName(String[] myImgFileName) { 59 this.myImgFileName = myImgFileName; 60 } 61 62 public String[] getMyImgContentType() { 63 return myImgContentType; 64 } 65 66 public void setMyImgContentType(String[] myImgContentType) { 67 this.myImgContentType = myImgContentType; 68 } 69 70 /** 71 * 将文件上传到指定文件 72 * 73 * @param input 74 * 上传文件 75 * @param ouput 76 * 保存文件 77 * */ 78 public int copy(File input, File output) { 79 InputStream in = null; 80 OutputStream out = null; 81 try { 82 FileInputStream fileIn = new FileInputStream(input); 83 FileOutputStream fileOut = new FileOutputStream(output); 84 85 in = new BufferedInputStream(fileIn, BUFFER_SIZE); 86 out = new BufferedOutputStream(fileOut, BUFFER_SIZE); 87 88 int length = 0; 89 byte[] buffer = new byte[BUFFER_SIZE]; 90 while (-1 != (length = in.read(buffer))) { 91 out.write(buffer, 0, length); 92 } 93 } 94 catch (IOException e) { 95 e.printStackTrace(); 96 } 97 finally { 98 try { 99 if (null != in) 100 in.close(); 101 if (null != out) 102 out.close(); 103 } 104 catch (IOException e) { 105 e.printStackTrace(); 106 } 107 } 108 109 return 0; 110 } 111 112 public String execute() throws Exception { 113 String parent = ServletActionContext.getServletContext().getRealPath("/filesave"); 114 File save = null; 115 //如果有上传文件 116 if (null != myImg) { 117 int size = myImg.length; 118 for (int i = 0; i < size; i++) { 119 save = new File(parent, myImgFileName[i]); 120 copy(myImg[i], save); 121 } 122 } 123 return SUCCESS; 124 } 125 }
因为是批量下载,第24~28行中,将变量设置为数组,也可是设置为集合。然后在116~121行中遍历所有上传的文件,逐个进行处理就可以了。这里要注意:需要声明的三个变量,其中File[]变量名XXX要和jsp文件上传的变量名一致,而FileName和ContentType的命名规则是要遵循XXXFileName和XXXContentType规则.
struts.xml:
1 <!-- 上传文件的action --> 2 <action name="upload" class="com.sunflower.upload.UploadAction"> 3 <interceptor-ref name="fileUpload"> 4 5 </interceptor-ref> 6 <interceptor-ref name="defaultStack"></interceptor-ref> 7 <result name="success" type="redirectAction"> 8 <param name="actionName">show</param> 9 </result> 10 </action>
可以在<constant/>标签中进行上传文件设置,在<constant/>标签中设置和在struts.properties中设置是一样的
<!-- 设置缓存文件存放路径 --> <constant name="struts.multipart.saveDir" value="E:\saveDir"></constant> <!-- 设置文件上传大小,最大值设为10M --> <constant name="struts.multipart.maxSize" value="10485760"></constant>
罗列上传信息:
ShowAction.java(得到所有上传的文件信息):
1 package com.sunflower.download; 2 3 import java.util.List; 4 5 import com.opensymphony.xwork2.ActionSupport; 6 import com.sunflower.util.MyFile; 7 import com.sunflower.util.ShowFileList; 8 9 @SuppressWarnings("serial") 10 public class ShowAction extends ActionSupport { 11 List<MyFile> myFile = null; 12 13 public List<MyFile> getMyFile() { 14 return myFile; 15 } 16 17 public void setMyFile(List<MyFile> myFile) { 18 this.myFile = myFile; 19 } 20 21 public String execute() throws Exception { 22 // 得到文件目录里面的所有文件信息 23 this.setMyFile(ShowFileList.getFileName()); 24 return SUCCESS; 25 } 26 }
第11中,List<MyFile>用来存放所上传的所有文件信息,MyFile是一个文件的实体类。 第23行中ShowFileList是遍历目录得到所有文件信息的功能类。
MyFile.java:
1 public class MyFile { 2 //文件名字 3 private String fileName; 4 //文件路径 5 private String filePath; 6 7 public String getFileName() { 8 return fileName; 9 } 10 11 public void setFileName(String fileName) { 12 this.fileName = fileName; 13 } 14 15 public String getFilePath() { 16 return filePath; 17 } 18 19 public void setFilePath(String filePath) { 20 this.filePath = filePath; 21 } 22 23 }
ShowFileList.java:
1 public class ShowFileList { 2 /** 得到所有文件 */ 3 public static File[] getFiles() { 4 String directory = ServletActionContext.getServletContext().getRealPath("/filesave"); 5 File parent = new File(directory); 6 return parent.listFiles(); 7 } 8 9 /** 得到所有文件的文件信息 */ 10 public static List<MyFile> getFileName() { 11 List<MyFile> list = null; 12 File[] file = getFiles(); 13 14 if (null != file) { 15 list = new ArrayList<MyFile>(); 16 for (int i = 0; i < file.length; i++) { 17 18 String name = file[i].getName(); 19 String path = file[i].getAbsolutePath(); 20 MyFile myFile = new MyFile(); 21 myFile.setFileName(name); 22 myFile.setFilePath(path); 23 24 list.add(myFile); 25 } 26 } 27 28 return list; 29 } 30 31 }
struts.xml:
<!-- 显示文件的Action --> <action name="show" class="com.sunflower.download.ShowAction"> <result name="success"> /downloadui/filedownload.jsp </result> </action>
得到所有文件信息后,将参数传递给filedownload.jsp显示
filedownload.jsp:
1 <html> 2 <head> 3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4 <title>文件下载</title> 5 </head> 6 <body> 7 <s:iterator value="myFile"> 8 <s:a href="download.action?filePath=%{filePath}&fileName=%{fileName}" ><s:property value="%{fileName}"/></s:a> 9 <br/> 10 </s:iterator> 11 </body> 12 </html>
第7行中的value="myFile"就是ShowAction里面的myFile.第7~10行中,利用迭代将所有文件信息放进超链接中罗列显示出来
文件下载:
download.action(处理文件下载的action):
1 public class DownloadAction extends ActionSupport { 2 //文件路径 3 private String filePath; 4 //文件名称 5 private String fileName; 6 7 public String getFilePath() { 8 return filePath; 9 } 10 11 public void setFilePath(String filePath) { 12 this.filePath = filePath; 13 } 14 15 public String getFileName() { 16 return fileName; 17 } 18 19 public void setFileName(String fileName) { 20 this.fileName = fileName; 21 } 22 23 /** 得到文件输入流 */ 24 public InputStream getSelectFile() throws Exception { 25 return new FileInputStream(new File(filePath)); 26 } 27 28 /** 将文件名转换成中文 */ 29 public String getDownloadName() throws Exception { 30 String downloadName = new String(fileName.getBytes(), "ISO8859-1"); 31 return downloadName; 32 } 33 34 @Override 35 public String execute() throws Exception { 36 return SUCCESS; 37 } 38 }
第24行中,getSelectFile()方法得到文件的输入流,和struts.xml中的<param name="inputName">selectFile</param>中的元素值对应,这个名字可以随便起,但返回类型一定为InputStream. getXXX和XXX对应. 第29~32行的方法是将文件名转换成中文类型,以便在struts.xml中引用。
struts.xml:
1 <!-- 下载文件的action --> 2 <action name="download" class="com.sunflower.download.DownloadAction"> 3 <result name="success" type="stream"> 4 <!-- 支持所有格式文件 --> 5 <param name="contentType">application/octet-stream;charset=ISO8859-1</param> 6 <!-- 得到输入流 --> 7 <param name="inputName">selectFile</param> 8 <param name="contentDisposition">attachment;filename="%{downloadName}"</param> 9 <param name="bufferSize">4096</param> 10 </result> 11 </action>
项目源代码下载:
http://115.com/file/dpjyajp7#fileupload.rar
文件上传参开文献:
http://www.blogjava.net/max/archive/2007/03/21/105124.html
文件下载参考文献:
http://pengranxiang.iteye.com/blog/259401