struts文件上传
最近项目中使用到文件上传的例子,用到struts中的文件上传及ftp简单总结下:
1.struts文件上传
2.ftp服务器搭建
3.struts上传文件到ftp组件
1.struts文件
struts文件上传相对比较简单,由于struts对文件上传进行了封装,上篇文章中说到的struts中的文件上传拦截器进行的处理,具体逻辑代码如下:
1 public String intercept(ActionInvocation invocation) throws Exception { 2 ActionContext ac = invocation.getInvocationContext(); 3 4 HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); 5 6 if (!(request instanceof MultiPartRequestWrapper)) { 7 if (LOG.isDebugEnabled()) { 8 ActionProxy proxy = invocation.getProxy(); 9 LOG.debug(getTextMessage("struts.messages.bypass.request", new String[]{proxy.getNamespace(), proxy.getActionName()})); 10 } 11 12 return invocation.invoke(); 13 } 14 15 ValidationAware validation = null; 16 17 Object action = invocation.getAction(); 18 19 if (action instanceof ValidationAware) { 20 validation = (ValidationAware) action; 21 } 22 23 MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; 24 25 if (multiWrapper.hasErrors()) { 26 for (String error : multiWrapper.getErrors()) { 27 if (validation != null) { 28 validation.addActionError(error); 29 } 30 } 31 } 32 33 // bind allowed Files===核心处理代码逻辑 34 //大体逻辑 35 //循环遍历前台input标签定义的name列表,每个name对应一个文件列表,遍历文件列表获取文件类型及文件内容 36 Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); 37 while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { 38 // get the value of this input tag获取前台定义的name属性 39 String inputName = (String) fileParameterNames.nextElement(); 40 41 // get the content type==获取文件类型 42 String[] contentType = multiWrapper.getContentTypes(inputName); 43 44 if (isNonEmpty(contentType)) { 45 // get the name of the file from the input tag==获取文件名 46 String[] fileName = multiWrapper.getFileNames(inputName); 47 48 if (isNonEmpty(fileName)) { 49 // get a File object for the uploaded File 50 File[] files = multiWrapper.getFiles(inputName); 51 if (files != null && files.length > 0) { 52 List<File> acceptedFiles = new ArrayList<File>(files.length); 53 List<String> acceptedContentTypes = new ArrayList<String>(files.length); 54 List<String> acceptedFileNames = new ArrayList<String>(files.length); 55 String contentTypeName = inputName + "ContentType"; 56 String fileNameName = inputName + "FileName"; 57 58 for (int index = 0; index < files.length; index++) { 59 if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation)) { 60 acceptedFiles.add(files[index]); 61 acceptedContentTypes.add(contentType[index]); 62 acceptedFileNames.add(fileName[index]); 63 } 64 } 65 66 if (!acceptedFiles.isEmpty()) { 67 Map<String, Object> params = ac.getParameters(); 68 //文件列表 69 params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); 70 //文件类型名称列表 71 params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); 72 //文件名称列表 73 params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); 74 } 75 } 76 } else { 77 if (LOG.isWarnEnabled()) { 78 LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new String[]{inputName})); 79 } 80 } 81 } else { 82 if (LOG.isWarnEnabled()) { 83 LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new String[]{inputName})); 84 } 85 } 86 } 87 88 // invoke action 89 return invocation.invoke(); 90 }
通过研究上面的代码可以明白文件上传的使用方法,比如下面页面:
前台页面代码如下
1 <div> 2 <label>附件上传1</label> 3 <input name="file" type="file"> 4 <input name="file" type="file"> 5 </div> 6 <div> 7 <label>附件上传2</label> 8 <input name="test" type="file"> 9 <input name="test" type="file"> 10 </div>
对于这样的前台定义,后台action中应该进行如下想关属性的配置
//对应前台页面中的name=“file”的一组定义 private List<File> file; private List<String> fileContentType; private List<String> fileFileName; public List<File> getFile() { return file; } public void setFile(List<File> file) { this.file = file; } public List<String> getFileContentType() { return fileContentType; } public void setFileContentType(List<String> fileContentType) { this.fileContentType = fileContentType; } public List<String> getFileFileName() { return fileFileName; } public void setFileFileName(List<String> fileFileName) { this.fileFileName = fileFileName; }
1 //对应前台name为test的属性文件列表 2 private List<File> test; 3 private List<String> testContentType; 4 private List<String> testFileName; 5 public List<File> getTest() { 6 return test; 7 } 8 9 public void setTest(List<File> test) { 10 this.test = test; 11 } 12 13 public List<String> getTestContentType() { 14 return testContentType; 15 } 16 17 public void setTestContentType(List<String> testContentType) { 18 this.testContentType = testContentType; 19 } 20 21 public List<String> getTestFileName() { 22 return testFileName; 23 } 24 25 public void setTestFileName(List<String> testFileName) { 26 this.testFileName = testFileName; 27 }