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的性能位居第一。