h***@126.com
h***@126.com
  • 发布:2016-09-18 18:32
  • 更新:2018-05-12 17:40
  • 阅读:2171

关于plus.uploader与Struts2的问题

分类:HTML5+

倒腾了一天,发现一个问题,到现在为止仍未得到解决,现把问题贴出来,希望遇到过的还能一起交流,同时也希望有经验的老师给一点指导

官方API在plus.Uploader中描述,addFile方法中,UploadFileOptions参数中,
Key:上传任务中如果已经存在相同key的上传文件或数据将导致添加文件失败。
官方API

但是我后台用的是Struts2框架,在获取多个文件上传时,采用的是setting方法注入模式。在Struts2注入时,获取form域中控件名称。若存在多个文件上传是时,form域中的name必须要一致。

例如:我同时上传三张图片时,应该有三个name为image的file控件

 <form action="xxxAction!xx.action" enctype="multipart/form-data" method="post">  
           文件1:<input type="file" name="image"><br/>  
           文件2:<input type="file" name="image"><br/>  
           文件3:<input type="file" name="image"><br/>  
    <input type="submit" value="上传" />  
    </form>

但是在plus.Uploader中的addFile方法中key是不允许相同的,也不报错,但后台永远只能收到一个文件。。

不知道大家是怎么用Strues2去接plus.Uploader中的多文件的。

解决办法:


原理:
跟进Struts2原代码可以知道,当请求被它栏截后代理工厂创建了一个新的Struts2 request对象,即:HttpServletRequest请求被转成了MultiPartRequestWrapper。原Apach的upload.parseRequest(request)上传的文件,将被丢弃。所以如需使用request,则需要将struts封装好的的MultiPartRequestWrapper转换成原来的HttpServletRequest,或压根就不要让Struts2去强转成自己的对象。

思路:
1、将MultiPartRequestWrapper转成HttpServletRequest,调试模式跟进可以看到,MultiPartRequestWrapper对象中的IO信息为NULL(Struts2 丢弃),所以没办法转回去,

2、不让Struts2栏截

解决办法:
1、将编写一个过滤器,设定请求策略,让Struts2栏截,注意,因为此策略的目的为摆脱Struts2的Requery工厂,但为了让Struts2其它优秀功能还存在,所以此策略最好区分于你原来的正常Struts2的请求策略,除非你完全不想要Struts2的Request。

<!-- 获取请求 -->  
    <filter>  
        <filter-name>myRequestFilter</filter-name>  
        <filter-class>com.zhhy.system.tool.servlet.filter.RqueryFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>myRequestFilter</filter-name>  
        <url-pattern>*.action</url-pattern>  
    </filter-mapping>

2、 重写过滤器中的doFilter方法,并抢先创建StrutsRequestWrapper。不要让Struts2代理去创建。自己创建时可以将request指定为HttpServletRequest对象。

@Override  
    public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  

        //获取请求  
        String uri = ((HttpServletRequest) request).getRequestURI();  
        System.out.println("当前请求:"+uri);  

        /**  
         * 脱离Struts2请求封装,必须显示的在你的请求中加入Wrapper关键字  
         * 例如:将原来的:systemAction!login.action 改为 systemWrapper!login.action  
         * 何智  
         * 2016年9月19日  
         */  
        int index = uri.lastIndexOf("Wrapper");  
        System.out.println(index);  
        if(-1 != index){  
            log.info("当前请求:" + uri + "为StrutsRequestWrapper方式请求,已对其不加载Strtus2封装..");  
            chain.doFilter(new StrutsRequestWrapper((HttpServletRequest) request), response);  
        }else{  
            //继续转发请求  
            chain.doFilter(request, response);  
            return;  
        }  

    }

3、此时,你可以在你的Action中这样去获取File了

/**  
   * 照片信息  
   */  
  try{  
   DiskFileItemFactory factory = new DiskFileItemFactory();    
         ServletFileUpload upload = new ServletFileUpload(factory);   
         upload.setSizeMax(1024 * 1024 * 100);  
         List<FileItem> fileItemList = upload.parseRequest(ServletActionContext.getRequest());  
         Iterator<FileItem> fileItemIterator = fileItemList.iterator();  
         FileItem fileItem = null;  

         while (fileItemIterator.hasNext()) {  

          fileItem = fileItemIterator.next();  
           /**  
            * 普通数据获取  
            */  
             if (fileItem.isFormField()) {  

              /**  
               * 因为绕开了Struts2框架,所以表单数据必须手工获取  
               */  
                 String filedName = fileItem.getFieldName();  
                 String filedValue = fileItem.getString("utf-8");// 编码格式  
                 .....  
              } else {  

                // 获取文件上传的文件名  
                 String OriginalFileName = RequestHtppUtile.takeOutFileName(fileItem.getName());  
                 ...  

                 }  
             }  
         }
2016-09-18 18:32 负责人:无 分享
已邀请:
h***@126.com

h***@126.com (作者)

已解决

有时间我再把完整的解决方案贴出来
我用的是struts2.3.15.1

5***@qq.com

5***@qq.com

你是怎么进行解决的?

6***@qq.com

6***@qq.com - 90后码农

楼主好方法! 我前面也遇到struts2多文件上传问题,情况跟楼主的有些差别,我是选择照片上传也是多文件的,循环将文件addFile,考虑到struts2 setting注入(不是file标签),然后我采用了一个笨办法就是在框架中配置了servlet,然后再配置struts2 不过滤servlet 然后通过servlet uploadFile 获取文件

该问题目前已经被锁定, 无法添加新回复