最近项目中使用到文件上传的例子,用到struts中的文件上传及ftp简单总结下:
1.struts文件上传
2.ftp服务器搭建
3.struts上传文件到ftp组件
1.struts文件
struts文件上传相对比较简单,由于struts对文件上传进行了封装,上篇文章中说到的struts中的文件上传拦截器进行的处理,具体逻辑代码如下:
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext ac = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
if (!(request instanceof MultiPartRequestWrapper)) {
if (LOG.isDebugEnabled()) {
ActionProxy proxy = invocation.getProxy();
LOG.debug(getTextMessage("struts.messages.bypass.request", new String[]{proxy.getNamespace(), proxy.getActionName()}));
}
return invocation.invoke();
}
ValidationAware validation = null;
Object action = invocation.getAction();
if (action instanceof ValidationAware) {
validation = (ValidationAware) action;
}
MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;
if (multiWrapper.hasErrors()) {
for (String error : multiWrapper.getErrors()) {
if (validation != null) {
validation.addActionError(error);
}
}
}
// bind allowed Files===核心处理代码逻辑
//大体逻辑
//循环遍历前台input标签定义的name列表,每个name对应一个文件列表,遍历文件列表获取文件类型及文件内容
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
// get the value of this input tag获取前台定义的name属性
String inputName = (String) fileParameterNames.nextElement();
// get the content type==获取文件类型
String[] contentType = multiWrapper.getContentTypes(inputName);
if (isNonEmpty(contentType)) {
// get the name of the file from the input tag==获取文件名
String[] fileName = multiWrapper.getFileNames(inputName);
if (isNonEmpty(fileName)) {
// get a File object for the uploaded File
File[] files = multiWrapper.getFiles(inputName);
if (files != null && files.length > 0) {
List<File> acceptedFiles = new ArrayList<File>(files.length);
List<String> acceptedContentTypes = new ArrayList<String>(files.length);
List<String> acceptedFileNames = new ArrayList<String>(files.length);
String contentTypeName = inputName + "ContentType";
String fileNameName = inputName + "FileName";
for (int index = 0; index < files.length; index++) {
if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation)) {
acceptedFiles.add(files[index]);
acceptedContentTypes.add(contentType[index]);
acceptedFileNames.add(fileName[index]);
}
}
if (!acceptedFiles.isEmpty()) {
Map<String, Object> params = ac.getParameters();
//文件列表
params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
//文件类型名称列表
params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
//文件名称列表
params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
}
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new String[]{inputName}));
}
}
} else {
if (LOG.isWarnEnabled()) {
LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new String[]{inputName}));
}
}
}
// invoke action
return invocation.invoke();
}
通过研究上面的代码可以明白文件上传的使用方法,比如下面页面:
前台页面代码如下
<div>
<label>附件上传1</label>
<input name="file" type="file">
<input name="file" type="file">
</div>
<div>
<label>附件上传2</label>
<input name="test" type="file">
<input name="test" type="file">
</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;
}
//对应前台name为test的属性文件列表
private List<File> test;
private List<String> testContentType;
private List<String> testFileName;
public List<File> getTest() {
return test;
}
public void setTest(List<File> test) {
this.test = test;
}
public List<String> getTestContentType() {
return testContentType;
}
public void setTestContentType(List<String> testContentType) {
this.testContentType = testContentType;
}
public List<String> getTestFileName() {
return testFileName;
}
public void setTestFileName(List<String> testFileName) {
this.testFileName = testFileName;
}