struts2文件上传

文件上传的方法,使用了struts的拦截器拦截action请求,把文件信息和存储字段信息保存到中间表中,这里只把保存的代码贴出来,展示和下载的方法实现起来比较多样,但是简单!

这里有一篇博客讲的是文件上传流程,可以参考学习:http://www.cnblogs.com/yjhrem/articles/2243007.html

 1 public class UploadFile extends SysEntity {
 2 
 3     private static final long serialVersionUID = 1L;
 4     
 5     存储文件名 6     private String storageFileName;
 7     上传文件名 8     private String uploadFileName;
 9     上传文件大小10     private String size;
11     文件类型12     private String contentType;
13     文件扩展名14     private String extName;
15     
16     public UploadFile() {
17     }
18     
19     public UploadFile(String storageFileName, String uploadFileName, String size,String contentType, String extName) {
20         this.storageFileName = storageFileName;
21         this.uploadFileName = uploadFileName;
22         this.size = size;
23         this.contentType = contentType;
24         this.extName = extName;
25     }
26   get set方法 省略.......
27 }

 

 
  3 import java.io.File;
  4 import java.io.IOException;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.util.ArrayList;
  7 import java.util.Collection;
  8 import java.util.Enumeration;
  9 import java.util.Iterator;
 10 import java.util.List;
 11 import java.util.UUID;
 12 import java.util.regex.Matcher;
 13 import java.util.regex.Pattern;
 14 
 15 import javax.servlet.http.HttpServletRequest;
 16 
 17 import org.apache.commons.beanutils.PropertyUtils;
 18 import org.apache.commons.io.FileUtils;
 19 import org.apache.commons.lang.StringUtils;
 20 import org.apache.commons.lang3.ArrayUtils;
 21 import org.apache.struts2.ServletActionContext;
 22 import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
 23 import org.slf4j.Logger;
 24 import org.slf4j.LoggerFactory;
 25 import org.springframework.mock.web.MockMultipartHttpServletRequest;
 26 import org.springframework.web.multipart.MultipartFile; 34 import com.opensymphony.xwork2.ActionContext;
 35 import com.opensymphony.xwork2.ActionInvocation;
 36 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 37 
 38 /**
 39  * 存储文件到服务器
 40  * 
 41  * 文件中可定义storageDIR属性(存储目录)[系统默认路径为应用发布路径/uploadFiles目录] 如果与
 42  * <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> 一同使用需要放置在其后面
 43  * @see org.apache.struts2.interceptor.FileUploadInterceptor
 44  */
 45 public class UploadFileInterceptor extends AbstractInterceptor {
 46 
 47     private static final long serialVersionUID = 1L;
 48 
 49     private static final Logger LOG = LoggerFactory.getLogger(UploadFileInterceptor.class);
 50     public final static String[] NO_SUFFIX_ALLOWED = new String[] { "sql", "jsp", "cmd", "bat", "sh", "exe" };//例外的文件格式
 51 
 52     public String intercept(ActionInvocation invocation) throws Exception {
 53         ActionContext ac = invocation.getInvocationContext();
 54         HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
 55         if (request instanceof MultiPartRequestWrapper && invocation.getAction() instanceof ActionParam) {
 56             savedFilesToServer((MultiPartRequestWrapper) request, invocation.getAction());
 57         }
 58         return invocation.invoke();
 59     }
 60 
 61     /**
 62      * 将文件存储到服务器
 63      * 
 64      * @return 存储文件名,上传文件名
 65      * @throws IOException
 66      */
 67     private void savedFilesToServer(MultiPartRequestWrapper multiWrapper, Object actionObj) {
 68         Enumeration<String> fileParameterNames = multiWrapper.getFileParameterNames();
 69         while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
 70             String formItemName = fileParameterNames.nextElement();
 71             if (!checkEntityProperty(actionObj, formItemName)) {// 检查目标是否符合要求
 72                 continue;
 73             }
 74             File storageDIRFile = SysUtils.getUploadDir();//这里获得上传文件的路径,配置在配置文件中
 75             if (!storageDIRFile.exists() || !storageDIRFile.isDirectory()) {
 76                 if (!storageDIRFile.mkdir()) {
 77                     LOG.error("[附件]文件上传失败,无法创建存储目录。请手工修改app.properties中的storageDIR存储路径[存储目录:" + storageDIRFile.getAbsoluteFile() + "]");
 78                     break;
 79                 }
 80             }
 81 
 82             File[] file = multiWrapper.getFiles(formItemName);
 83             String[] fileName = multiWrapper.getFileNames(formItemName);
 84             String[] contentType = multiWrapper.getContentTypes(formItemName);
 85             String uploadFileIds = "";
 86             List<UploadFile> ufs = new ArrayList<UploadFile>();
 87             BaseDAO dao = SpringContextUtil.getBean("baseDAO");//获得带有sessionFactory的对象
 88             for (int index = 0; index < file.length; index++) {
 89                 File currentFile = file[index];
 90                 if (!currentFile.exists()) {
 91                     continue;
 92                 }
 93 
 94                 String uploadFileName = fileName[index];
 95                 String extName = getExtName(uploadFileName);
 96                 if (ArrayUtils.contains(NO_SUFFIX_ALLOWED, extName.toLowerCase())) {
 97                     LOG.warn("[附件]:" + extName);
 98                     throw new BizException("不被允许上传的文件!文件名:" + uploadFileName);
 99                 }
100                 if (currentFile.length() < 1) {
101                     throw new BizException("上传的文件大小为0,请重新选择!");
102                 }
103 
104                 String storageFileName = UUID.randomUUID().toString() + "." + extName;
105                 File storageFile = new File(storageDIRFile, storageFileName);
106                 // 步骤1:存储文件到文件系统
107                 try {
108                     FileUtils.copyFile(currentFile, storageFile);
109                     LOG.debug("[附件]已将文件" + uploadFileName + "存储到 " + storageDIRFile.getAbsolutePath() + " 目录中,存储文件名为: " + storageFileName);
110                 } catch (Exception e) {
111                     LOG.error("[附件]文件存储失败,文件信息[文件名:" + uploadFileName + ",文件大小:" + currentFile.length() + "]", e);
112                 }
113 
114                 // 步骤2:存储文件信息到文件表
115                 UploadFile uf = new UploadFile(storageFileName, uploadFileName, String.valueOf(currentFile.length()), contentType[index], extName);
116                 try {
117                     dao.saveUpdate(uf);//将文件信息保存到数据中库
118                     ufs.add(uf);
119                     dao.flush();//flush session
120                 } catch (Exception e) {
121                     LOG.error("[附件]无法将文件信息存入文件表,错误信息:", e);
122                     FileUtils.deleteQuietly(storageFile);// 回滚事务
123                     break;
124                 }
125 
126                 uploadFileIds += "," + uf.getId();
127             }
128 
129             // 步骤3:添加编辑中的文件(id存储在hidden中)
130             String[] hiddenFileIds = multiWrapper.getParameterValues(formItemName);
131             if (hiddenFileIds != null && hiddenFileIds.length > 0) {
132                 uploadFileIds += "," + StringUtils.join(hiddenFileIds, ",");
133             }
134 
135             try {
136                 // 步骤4:存储文件表ID到业务实体属性
137                 if (uploadFileIds.length() > 1) {
138                     uploadFileIds = uploadFileIds.substring(1);
139                 }
140                 //匹配一对多关系中多的一方需要上传附件
141                 Matcher matcher = Pattern.compile("\\[\\d*\\]").matcher(formItemName);
142                 if (matcher.find()) {
143                     String[] fileSystemNames = multiWrapper.getFileSystemNames(formItemName);
144                     String[] fields = matcher.replaceAll("").split("\\.");
145                     if (fields.length == 1) {// members[1] 仅支持集合,不支持数组
146                         setFileId2Collection(uploadFileIds, fileSystemNames, fields[0], PropertyUtils.getProperty(actionObj, fields[0]), actionObj);
147                     } else if (fields.length == 2) {// members[1].fileId
148                         setFileId2Collection(uploadFileIds, fileSystemNames, fields[1], PropertyUtils.getProperty(actionObj, fields[0]), null);
149                     } else if (fields.length == 3) {// entity.members[1].fileId
150                         setFileId2Collection(uploadFileIds, fileSystemNames, fields[2],
151                                 PropertyUtils.getProperty(actionObj, fields[0] + "." + fields[1]), null);
152                     } else {
153                         PropertyUtils.setProperty(actionObj, formItemName, uploadFileIds);
154                     }
155                 } else {
156                     PropertyUtils.setProperty(actionObj, formItemName, uploadFileIds);
157                 }
158             } catch (Exception e) {
159                 LOG.error("[附件]无法为附件属性赋值[Action对象名:" + actionObj.toString() + ",属性名:" + formItemName + "]", e);
160                 for (UploadFile uf : ufs) {
161                     dao.delEntity(uf);
162                     FileUtils.deleteQuietly(new File(storageDIRFile, uf.getStorageFileName()));// 回滚事务
163                 }
164                 dao.flush();
165             }
166         }
167     }
168 
169     private void setFileId2Collection(String uploadFileIds, String[] fileSystemNames, String field, Object obj, Object root)
170             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
171         Iterator<?> iterator = Collection.class.cast(obj).iterator();
172         boolean setted = false;
173         int index = 0;
174         while (iterator.hasNext()) {
175             if (setted) {
176                 break;
177             }
178 
179             Object next = iterator.next();
180             String tempFilePath = String.valueOf(null == root ? PropertyUtils.getProperty(next, field) : next);
181             for (int i = 0; i < fileSystemNames.length; i++) {
182                 if (tempFilePath.indexOf(fileSystemNames[i]) != -1) {
183                     if (null == root) {
184                         PropertyUtils.setProperty(next, field, uploadFileIds);
185                     } else {
186                         PropertyUtils.setProperty(root, field + "[" + index + "]", uploadFileIds);
187                     }
188                     setted = true;
189                     break;
190                 }
191             }
192 
193             index++;
194         }
195     }
196 
197     /**
198      * 获取扩展名
199      * 
200      * @param fileName
201      * @return
202      */
203     private String getExtName(String fileName) {
204         return StringUtils.substringAfterLast(fileName, ".");
205     }
206 
207     /**
208      * 检查实体属性
209      * 
210      * @param bean
211      * @param formItemName
212      * @return
213      */
214     private boolean checkEntityProperty(Object bean, String formItemName) {
215         boolean flag = true;
216         try {
217             Matcher matcher = Pattern.compile("\\[\\d*\\]").matcher(formItemName);
218             if (matcher.find()) {
219                 formItemName = matcher.replaceAll("[0]");
220             }
221 
222             Class<?> type = PropertyUtils.getPropertyType(bean, formItemName);
223             if (!String.class.equals(type)) {
224                 LOG.warn("[附件上传]业务实体中提供接收附件的属性非String类型,无法将附件表ID赋值到该属性中。修改属性类型。[Action对象名:" + bean.toString() + ",属性名" + formItemName + ",属性类型:"
225                         + type.getName() + "]");
226                 flag = false;
227             }
228         } catch (Exception e) {
229             LOG.warn("[附件上传]未找到对应属性,无法为附件属性赋值。请确认属性名和表单项名是否一致[附件表单项名:" + formItemName + "]");
230             flag = false;
231         }
232 
233         return flag;
234     }
235 }

这里需要考虑的是输入我这条记录的文件在删除的时候并不会删除UploadFile表中的数据,当然也不会删除我们保存的文件,长远考虑应该删除;

posted @ 2016-08-21 17:43  user_孙  阅读(521)  评论(0编辑  收藏  举报