天天看点

修正Strut2 自带上传拦截器功能

struts2字典的fileuploadinterceptor 拦截器 主要帮助获取上传文件的contenttype、filename、文件对象。如果开发人员在开发过程中使用。则需要设置set/get方法:

比如

setxxxcontenttype() 

getxxxfilename() 

getxxxcontenttype() 

setxxxfilename() 

getxxxfile() 

setxxxfile()

其中,"xxx"为渲染器的name.

问题在这里

第一,如果除了contenttype/file/filename ,还需要其他的消息怎么办呢。拦截器就无能为力了。 这个可以忽略。

第二,平时在开发过程中,我们经常有动态添加附件功能。如果上传的附件同属于一类的话,还尚可。但是,如果一个页面中,需要上传多种类型的附件,而且每个附件类型动态增加的。拦截器就有点力不从心了。只能针对每个类型的附件,在action中写多个方法。

settype1file();

settype2file();

settype1contenttype();

settype2contenttype();

settype1filename();

settype2filename();

---------

问题在这里。如果我再增加一个类型呢?

在深层挖掘一下,如果我想做一个公共的文件上传处理类,怎么办。

本人研究了下自带的拦截器,在此基础上,通过自己的实践,提出自己的一个解决方案。

我通过map 来管理上传的文件列表。这样就不惧怕多类型文件上传,且可扩展性也提高了。

修正后的strut2 fileuploadinterceptor 如下

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 object[]{proxy.getnamespace(), proxy.getactionname()}, ac.getlocale())); 

                        } 

                        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); 

                                } 

                                log.warn(error); 

                // bind allowed files 

                enumeration fileparameternames = multiwrapper.getfileparameternames(); 

                map<string,list<map<string,object>>> fileparametermap = new hashmap<string,list<map<string,object>>>();//文件值对 //zhaogy 

                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 

                                        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); 

                                                list<string> rendernames = 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, ac.getlocale())) { 

                                                                acceptedfiles.add(files[index]); 

                                                                acceptedcontenttypes.add(contenttype[index]); 

                                                                acceptedfilenames.add(filename[index]); 

                                                                list<map<string, object>> vfl=null; 

                                                                if(fileparametermap.containskey(inputname)){//是否已存在

                                                                  vfl = fileparametermap.get(inputname); 

                                                                }else{ 

                                                                  vfl = new arraylist<map<string,object>>(); 

                                                                  fileparametermap.put(inputname, vfl); 

                                                                } 

                                                                  map<string, object> value = new hashmap<string,object>(); 

                                                                  value.put("contenttype", contenttype[index]); 

                                                                  value.put("filename", filename[index]); 

                                                                  value.put("acceptedfile", files[index]); 

                  vfl.add(value); 

                                                        } 

                                                } 

                                                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()])); 

                                                        params.put("fileparametermap", fileparametermap);// zhaogy 

                                        } 

                                } else { 

                                        log.warn(gettextmessage(action, "struts.messages.invalid.file", new object[]{inputname}, ac.getlocale())); 

                        } else { 

                                log.warn(gettextmessage(action, "struts.messages.invalid.content.type", new object[]{inputname}, ac.getlocale())); 

                // invoke action 

                string result = invocation.invoke(); 

                // cleanup 

                fileparameternames = multiwrapper.getfileparameternames(); 

                        string inputvalue = (string) fileparameternames.nextelement(); 

                        file[] files = multiwrapper.getfiles(inputvalue); 

                        for (file currentfile : files) { 

                                if (log.isinfoenabled()) { 

                                        log.info(gettextmessage(action, "struts.messages.removing.file", new object[]{inputvalue, currentfile}, ac.getlocale())); 

                                if ((currentfile != null) && currentfile.isfile()) { 

                                        if (currentfile.delete() == false) { 

                                                log.warn("resource leaking:    could not remove uploaded file '" + currentfile.getcanonicalpath() + "'."); 

                return result; 

        }

测试代码:

/* 

* $id: multiplefileuploadusinglistaction.java 660522 2008-05-27 14:08:00z jholmes $ 

* licensed to the apache software foundation (asf) under one 

* or more contributor license agreements.    see the notice file 

* distributed with this work for additional information 

* regarding copyright ownership.    the asf licenses this file 

* to you under the apache license, version 2.0 (the 

* "license"); you may not use this file except in compliance 

* with the license.    you may obtain a copy of the license at 

*    http://www.apache.org/licenses/license-2.0 

* unless required by applicable law or agreed to in writing, 

* software distributed under the license is distributed on an 

* "as is" basis, without warranties or conditions of any 

* kind, either express or implied.    see the license for the 

* specific language governing permissions and limitations 

* under the license. 

*/ 

// start snippet: entire-file 

package org.apache.struts2.showcase.fileupload; 

import java.io.file; 

import java.util.arraylist; 

import java.util.iterator; 

import java.util.list; 

import java.util.map; 

import com.opensymphony.xwork2.actionsupport; 

/** 

* showcase action - multiple file upload using list 

* @version $date: 2008-05-27 16:08:00 +0200 (tue, 27 may 2008) $ $id: multiplefileuploadusinglistaction.java 660522 2008-05-27 14:08:00z jholmes $ 

public class multiplefileuploadusinglistaction extends actionsupport { 

        private list<file> uploads = new arraylist<file>(); 

        private list<string> uploadfilenames = new arraylist<string>(); 

        private list<string> uploadcontenttypes = new arraylist<string>(); 

  public void setfileparametermap( 

      map<string, list<map<string, object>>> fileparametermap) { 

    this.fileparametermap = fileparametermap; 

  } 

  public list<file> getupload() { 

                return this.uploads; 

        } 

        public void setupload(list<file> uploads) { 

                this.uploads = uploads; 

        public list<string> getuploadfilename() { 

                return this.uploadfilenames; 

        public void setuploadfilename(list<string> uploadfilenames) { 

                this.uploadfilenames = uploadfilenames; 

        public list<string> getuploadcontenttype() { 

                return this.uploadcontenttypes; 

        public void setuploadcontenttype(list<string> contenttypes) { 

                this.uploadcontenttypes = contenttypes; 

        private map<string,list<map<string,object>>> fileparametermap; 

        public map<string, list<map<string, object>>> getfileparametermap() { 

    return fileparametermap; 

        public string upload() throws exception { 

          iterator<string> iter = this.fileparametermap.keyset().iterator(); 

    while(iter.hasnext()){ 

             string key = iter.next(); 

             list<map<string, object>>    vs = this.fileparametermap.get(key); 

             system.out.println("key========"+key); 

             for(map<string, object> v : vs){ 

                object contenttype = v.get("contenttype"); 

                object filename = v.get("filename"); 

              object file =    v.get("acceptedfile"); 

              system.out.println("contenttype>>"+contenttype); 

              system.out.println("filename>>"+filename); 

              system.out.println("file>>"+file); 

             } 

          } 

//                system.out.println("\n\n upload1"); 

//                system.out.println("files:"); 

//                for (file u: uploads) { 

//                        system.out.println("*** "+u+"\t"+u.length()); 

//                } 

//                system.out.println("filenames:"); 

//                for (string n: uploadfilenames) { 

//                        system.out.println("*** "+n); 

//                system.out.println("content types:"); 

//                for (string c: uploadcontenttypes) { 

//                        system.out.println("*** "+c); 

//                system.out.println("\n\n"); 

                return success; 

// end snippet: entire-file

输出

key========upload2

contenttype>>application/octet-stream

filename>>xm_xvs.cfg

file>>d:\tomcat-6.0.20\work\catalina\localhost\struts2-showcase\upload_8c1aaae_1372ca9bef5__8000_00000011.tmp

contenttype>>text/html

filename>>login.html

file>>d:\tomcat-6.0.20\work\catalina\localhost\struts2-showcase\upload_8c1aaae_1372ca9bef5__8000_00000012.tmp

key========upload

contenttype>>text/plain

filename>>说明.txt

file>>d:\tomcat-6.0.20\work\catalina\localhost\struts2-showcase\upload_8c1aaae_1372ca9bef5__8000_00000008.tmp

contenttype>>application/vnd.openxmlformats-officedocument.wordprocessingml.document

filename>>孕妇饮食注意事项.docx

file>>d:\tomcat-6.0.20\work\catalina\localhost\struts2-showcase\upload_8c1aaae_1372ca9bef5__8000_00000009.tmp