在 Primefaces 5.1 中使用多个文件上传文件失败 [英] File-upload with multiple files fails in Primefaces 5.1

查看:18
本文介绍了在 Primefaces 5.1 中使用多个文件上传文件失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 PF 5.1 和 OmniFaces 1.7 版在 primefaces 中上传文件.

我的 .xhtml 代码:

<h:form id="fileImportForm" styleClass="prepend-top"prependId="false"><div style='margin-bottom:10px'><h:outputLabel value="#{msg.file_import_msg}"/>

<p:fileUpload id="fileImport" fileUploadListener="#{fileImport.handleFileUpload}"模式=高级"更新=消息"多个=真"label="#{msg.file_import_choose_label}"uploadLabel="#{msg.file_import_upload_label}"cancelLabel="#{msg.file_import_cancel_label}"/><p:growl id="messages" showDetail="true"/></h:form>

我的支持bean:

package test.boundary;导入 javax.inject.Named;导入 org.primefaces.event.FileUploadEvent;进口 com.haslerrail.aura.common.exception.SystemException;/*** 用于 <code>fileImport.xhtml</code> 的 BackingBean页.**/@命名公共类 FileImport 实现 java.io.Serializable {private static final long serialVersionUID = 1L;public void handleFileUpload(final FileUploadEvent event) 抛出 SystemException, InterruptedException {if (event == null || event.getFile() == null || event.getFile().getSize() == 0) {System.out.println("没有文件");}System.out.println(event.getFile().getFileName());线程睡眠(500);//稍等片刻强制异常!}}

问题是,当我的 handleFileUpload 函数解析上传的文件需要更长的时间时(Thread.sleep(500),它会抛出异常!仅当我同时上传多个文件时才会发生异常时间.

例外:

09:47:33,171 WARN [org.jboss.weld.Conversation] WELD-000315 未能在 1,000 中获取对话锁定,用于 ID 为 1 的对话09:47:33,180 严重 [org.omnifaces.exceptionhandler.FullAjaxExceptionHandler] FullAjaxExceptionHandler:处理 JSF ajax 请求期间发生异常.将显示错误页面/pages/error/error.xhtml".:org.jboss.weld.context.BusyConversationException:WELD-000322 对话锁定超时:1在 org.jboss.weld.context.AbstractConversationContext.activate(AbstractConversationContext.java:215) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]在 org.jboss.weld.jsf.WeldPhaseListener.activateConversations(WeldPhaseListener.java:108) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]在 org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:85) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]在 com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228) [jsf-impl-2.1.7-jbossorg-2.jar:]在 com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99) [jsf-impl-2.1.7-jbossorg-2.jar:]在 com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116) [jsf-impl-2.1.7-jbossorg-2.jar:]在 com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]在 org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:102) [primefaces-5.1.jar:5.1]在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]在 org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]在 org.omnifaces.filter.CacheControlFilter.doFilter(CacheControlFilter.java:226) [omnifaces-1.7.jar:1.7]在 org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:77) [omnifaces-1.7.jar:1.7]在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:489) [jbossweb-7.0.13.Final.jar:]在 org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]在 org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]在 org.apache.tomcat.util.net.JioEndpoint$Worker.run(JioEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]在 java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]

对我来说,这看起来像是 PF 5.1 中的一个错误!还有其他想法吗?

解决方案

p:fileUpload multiple="true" 在自己的请求中上传每个文件.问题是,请求同时发生,在您的情况下,这会触发对话锁定超时,因为每个请求都尝试访问相同的对话.另一个问题是JSF实际上需要客户端代码顺序发送请求,而它的服务器端代码不是线程安全的.

我建议按顺序发送上传请求.有多种方法可以实现这一点.

  1. PrimeFaces 5.2.6 及更高版本:您应该能够只使用 sequential 属性:

    <p:fileUpload Sequential="true" ...

    (该属性在 PF 问题 #403 中实现.)

  2. 这个答案 建议了一种通过 Javascript 的方法,即配置 PrimeFaces 使用的 jQuery 文件上传插件.

  3. 添加焊接依赖项.然后您可以更改默认锁定超时(以不可移植的 CDI 方式),以便请求在服务器上形成一个队列.默认锁定超时为 1 秒.以下代码更改了所有会话的全局锁定超时.

    import javax.enterprise.context.ConversationScoped;导入 javax.enterprise.context.Initialized;导入 javax.enterprise.event.Observes;导入 javax.inject.Inject;导入 javax.servlet.ServletRequest;导入 org.jboss.weld.context.http.HttpConversationContext;公共类 ConversationTimeoutDefaultSetter {@注入私人 HttpConversationContext ctx;公共无效对话初始化(@Observes @Initialized(ConversationScoped.class)ServletRequest 有效载荷) {ctx.setConcurrentAccessTimeout(10000L);//10 秒}}

更新:我忘记了,Initialized 需要 CDI 1.1,而您似乎使用的是 1.0.您可以在开始开始对话时设置超时时间.

I try to do a file upload in primefaces with PF 5.1 and OmniFaces version 1.7.

My .xhtml code:

<h:form id="fileImportForm" styleClass="prepend-top"
    prependId="false">

    <div style='margin-bottom:10px'>
        <h:outputLabel value="#{msg.file_import_msg}"/>
    </div>
    <p:fileUpload id="fileImport" fileUploadListener="#{fileImport.handleFileUpload}"   
        mode="advanced"  
        update="messages"   
        multiple="true"
        label="#{msg.file_import_choose_label}" 
        uploadLabel="#{msg.file_import_upload_label}" 
        cancelLabel="#{msg.file_import_cancel_label}"       
    />  
    <p:growl id="messages" showDetail="true"/>  

</h:form>

My backing bean:

package test.boundary;

import javax.inject.Named;
import org.primefaces.event.FileUploadEvent;
import com.haslerrail.aura.common.exception.SystemException;

/**
 * BackingBean for <code>fileImport.xhtml</code> page.
 *
 */
@Named
public class FileImport implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    public void handleFileUpload(final FileUploadEvent event) throws SystemException, InterruptedException {

        if (event == null || event.getFile() == null || event.getFile().getSize() == 0) {
            System.out.println("No file");

        }
        System.out.println(event.getFile().getFileName());
        Thread.sleep(500); // wait a little to force the exception!
    }
}

The problem is, when my handleFileUpload function takes a little bit longer to parse the uploaded file (Thread.sleep(500), it throws an exception! The exception only occurs when I'm uploading more than one file at the same time.

The exception:

09:47:33,171 WARN  [org.jboss.weld.Conversation] WELD-000315 Failed to acquire conversation lock in 1,000 for Conversation with id: 1
09:47:33,180 SEVERE [org.omnifaces.exceptionhandler.FullAjaxExceptionHandler] FullAjaxExceptionHandler: An exception occurred during processing JSF ajax request. Error page '/pages/error/error.xhtml' will be shown.: org.jboss.weld.context.BusyConversationException: WELD-000322 Conversation lock timed out: 1
    at org.jboss.weld.context.AbstractConversationContext.activate(AbstractConversationContext.java:215) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.jsf.WeldPhaseListener.activateConversations(WeldPhaseListener.java:108) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.jboss.weld.jsf.WeldPhaseListener.beforePhase(WeldPhaseListener.java:85) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:102) [primefaces-5.1.jar:5.1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.omnifaces.filter.CacheControlFilter.doFilter(CacheControlFilter.java:226) [omnifaces-1.7.jar:1.7]
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:77) [omnifaces-1.7.jar:1.7]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:489) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_75]  

For me it looks like an error in PF 5.1! Any other ideas?

解决方案

p:fileUpload multiple="true" uploads each file in its own request. Problem is, the requests happen simultaneously, which in your case triggers conversation lock timeout, since each request tries to access the same conversation. Another problem is that JSF actually requires client-side code to send requests sequentially, and its server-side code is not thread-safe.

I advise making the upload requests happen sequentially. There are multiple ways to achieve this.

  1. PrimeFaces 5.2.6 and above: you should be able to just use the sequential attribute:

    <p:fileUpload sequential="true" ...
    

    (The attribute was implemented in PF Issue #403.)

  2. This answer suggests a way via Javascript, by configuring the jQuery File Upload Plugin, which PrimeFaces uses.

  3. Add a Weld dependency. Then you could change the default lock timeout (in a non-portable CDI way), so the requests form a queue on the server. The default lock timeout is 1 second. The following code changes lock timeout globally for all conversations.

    import javax.enterprise.context.ConversationScoped;
    import javax.enterprise.context.Initialized;
    import javax.enterprise.event.Observes;
    import javax.inject.Inject;
    import javax.servlet.ServletRequest;
    import org.jboss.weld.context.http.HttpConversationContext;
    
    public class ConversationTimeoutDefaultSetter {
    
        @Inject
        private HttpConversationContext ctx;
    
        public void conversationInitialized(
                @Observes @Initialized(ConversationScoped.class)
                ServletRequest payload) {
            ctx.setConcurrentAccessTimeout(10000L); // 10 seconds
        }
    
    }
    

Update: I forgot, that Initialized requires CDI 1.1, and you seem to be using 1.0. You can set the timeout when you're beginning your conversation.

这篇关于在 Primefaces 5.1 中使用多个文件上传文件失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆