Struts2因License的原因早就不再支持Cos上传了,具体见 http://struts.apache.org/2.1.6/docs/file-upload.html 的官方说明:
There was a third alternative, cos, but it was removed due to licensing incompatibilities.
目前是内嵌了commons-fileupload,同时通过plugin方式支持Pell。但是struts.properties依然没有更新,网上的文章也依然是通过修改struts.multipart.parser对应的值为cos来自动支持Cos。
我们先不考虑license因素,看看让Struts2怎么支持Cos:
1) 创建一个实现org.apache.struts2.dispatcher.multipart.MultiPartRequest借口的类
/**
* @author <a href="http://intolong.spaces.live.com/">Jalen</a>
*/
public class CosMultiPartRequest implements MultiPartRequest {
private MultipartRequest multi;
private String defaultEncoding;
private boolean maxSizeProvided;
private int maxSize;
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
public void setDefaultEncoding(String defaultEncoding) {
this.defaultEncoding = defaultEncoding;
}
@Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)
public void setMaxSize(String maxSize) {
this.maxSizeProvided = true;
this.maxSize = Integer.parseInt(maxSize);
}
@Override
public String[] getContentType(String fieldName) {
return new String[] { multi.getContentType(fieldName) };
}
@SuppressWarnings("unchecked")
@Override
public List getErrors() {
return Collections.EMPTY_LIST;
}
@Override
public File[] getFile(String fieldName) {
return new File[] { multi.getFile(fieldName) };
}
@Override
public String[] getFileNames(String fieldName) {
return new String[] { multi.getFile(fieldName).getName() };
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getFileParameterNames() {
return multi.getFileNames();
}
@Override
public String[] getFilesystemName(String name) {
return new String[] { multi.getFilesystemName(name) };
}
@Override
public String getParameter(String name) {
return multi.getParameter(name);
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getParameterNames() {
return multi.getParameterNames();
}
@Override
public String[] getParameterValues(String name) {
return multi.getParameterValues(name);
}
@Override
public void parse(HttpServletRequest request, String saveDir) throws IOException {
if (maxSizeProvided) {
multi = new MultipartRequest(request, saveDir, maxSize, defaultEncoding);
} else {
multi = new MultipartRequest(request, saveDir, defaultEncoding);
}
}
}
2) 修改struts.xml,指定你的parser
<constant name="struts.multipart.parser" value="cos" />
这个也可以通过修改struts.properties来,效果相同
3) 修改struts.xml,注册你的parser
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="cos" class="jalen.core.struts2.CosMultiPartRequest" />
大功告成。
以下转贴个Cos和其他上传lib的性能对比,我自己并未实测:
处理基于http的文件上传,有这么几个opensource lib,O'Reilly的Cos,Apache的fileupload,还有JspSmart的SmartUpload。
网上查了下他们的性能对比,摘录如下:
使用2M、20M、45M、200M的上传大小测试三种组件所花费的时间(单位为ms)结果是:
2M
| 第1次 | 第2次 | 第3次 | 第4次 | 平均 |
Cos | 297 | 203 | 234 | 245 | 245 |
FileUpload | 281 | 312 | 281 | 312 | 297 |
SmartUpload | 531 | 594 | 485 | 532 | 536 |
20M
| 第1次 | 第2次 | 第3次 | 第4次 | 平均 |
Cos | 2562 | 2109 | 2719 | 2172 | 2391 |
FileUpload | 4062 | 4140 | 5360 | 3922 | 4371 |
SmartUpload | 3453 | 3094 | 3078 | 3547 | 3293 |
45M
| 第1次 | 第2次 | 第3次 | 第4次 | 平均 |
Cos | 4860 | 4844 | 5125 | 5171 | 5000 |
FileUpload | 9000 | 8391 | 10375 | 10078 | 9461 |
SmartUpload | 8265 | 9187 | 8672 | 8856 | 8745 |
200M
| 第1次 | 第2次 | 第3次 | 第4次 | 平均 |
Cos | 55813 | 52282 | 54796 | 51187 | 53520 |
FileUpload | 76343 | 68531 | 80954 | 79031 | 76215 |
SmartUpload | 内存堆栈溢出 |
|
|
|
|
从上述的表格对比中可以看出Cos始终保持着良好的性能。在上传量较小(容量<2M,这是最常出现的情况)时,Cos比FileUpload性能并没有好很多,但SmartUpload就已经开始显出弱势。随着容量的增大,FileUpload和SmartUpload的性能下降非常快,直到200M容量时,SmartUpload已经不堪重负崩溃了,而Cos此时的花费时间比FileUpload少了20多秒,不能不说在本次的评测中,Cos的性能位居第一。