SSH与SSM学习之SSH实现CRM练习12——文件上传原理
一、主要说明
其实文件上传,主要就是通过 FileUploadInterceptor 这个拦截器,配合 ParametersInterceptor来完成的。
FileUploadInterceptor 把上传的文件 添加到值栈中,ParametersInterceptor 取出添加的值,赋值到对应的Action的属性中。
下面我们具体来看一下。
二、查看 struts-default.xml
我使用的是 struts 2.5
如下地址:
web\WEB-INF\lib\struts2-core-2.5.13.jar!\struts-default.xml
主要看到下面
.....
<interceptors>
.......
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<interceptor name="i18n" class="org.apache.struts2.interceptor.I18nInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
.......
<interceptor-stack name="defaultStack">
.......
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="datetime"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params"/>
.......
</interceptor-stack>
.......
</interceptors>
.....
上面我们可以看到,默认的拦截器栈中,先调用 fileUpload,然后才是 params
三、FileUploadInterceptor.java
主要就是完成,获取文件、文件名、文件的ContentType 添加到值栈中,最后会调用到 ParametersInterceptor,赋值给Action中对应的属性。
public class FileUploadInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
.......
// bind allowed Files
Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
// get the value of this input tag
//获取文件的对应的属性名
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
UploadedFile[] files = multiWrapper.getFiles(inputName);
if (files != null && files.length > 0) {
List<UploadedFile> acceptedFiles = new ArrayList<>(files.length);
List<String> acceptedContentTypes = new ArrayList<>(files.length);
List<String> acceptedFileNames = new ArrayList<>(files.length);
//拼接文件的ContentType属性名
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, Parameter> newParams = new HashMap<>();
//把文件添加到值栈中
newParams.put(inputName, new Parameter.File(inputName, acceptedFiles.toArray(new UploadedFile[acceptedFiles.size()])));
//把文件的ContentType添加到值栈中
newParams.put(contentTypeName, new Parameter.File(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])));
//把文件名添加到值栈中
newParams.put(fileNameName, new Parameter.File(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])));
ac.getParameters().appendAll(newParams);
}
}
} 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}));
}
}
}
return invocation.invoke();
}
}