当使用PrettyFaces调用FileUploadListener时,ViewScoped bean被重建 [英] ViewScoped bean rebuilt when FileUploadListener called using PrettyFaces

查看:139
本文介绍了当使用PrettyFaces调用FileUploadListener时,ViewScoped bean被重建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 JSF 2.1.5 应用程序中插入了< p:fileUpload /> 组件。我正在使用 PrimeFaces 3.4.1 。这个组件由一个 @ViewScoped bean支持。我有这样的表单:

 <?xml version ='1.0'encoding ='UTF-8'?> ; 
xmlns:ui =http://java.sun.com/jsf/facelets
xmlns:f =http://java.sun.com/jsf/core
xmlns:h =http://java.sun.com/jsf/html
xmlns :c =http://java.sun.com/jsp/jstl/core
xmlns:p =http://primefaces.org/ui
template =/ templates / general_template .xhtml>

< ui:define name =metadata>
< f:元数据>

< f:viewParam id =NavIndexname =NavIndex
value =#{navegableMassiveUserAdd._QueueIndex}/>
< f:event type =preRenderView
listener =#{navegableMassiveUserAdd.initialize}/>
< / f:元数据>
< / ui:define>

< ui:define name =general_content>
< h:form>

< p:fileUpload
fileUploadListener =#{navegableMassiveUserAdd.listener}
mode =advancedallowTypes =/(\。| \ /)( xls | csv)$ /
label =#{msg.SELECT}multiple =false/>

< p:commandButton id =cancelButton
action =#{navegableMassiveUserAdd.actionCancelAdd}
value =#{msg.CANCELAR}ajax =false style =margin:9px 0px 5px; />
< / h:表格>
< / ui:define>



这是我的主要模板:

 <?xml version ='1.0'encoding ='UTF-8'?> 
<!DOCTYPE html PUBLIC - // W3C // DTD XHTML 1.0 Transitional // EN
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional。 DTD>

xmlns:ui =http://java.sun.com/jsf / facelets
xmlns:f =http://java.sun.com/jsf/core
xmlns:h =http://java.sun.com/jsf/html
xmlns:c =http://java.sun.com/jsp/jstl/core
xmlns:p =http://primefaces.org/uixmlns:o =http: //omnifaces.org/ui\">


< h:head>
< meta http-equiv =PragmaCONTENT =no-cache>< / meta>
< meta http-equiv =cache-controlcontent =no-cache>< / meta>
< meta http-equiv =ExpiresCONTENT = - 1>< / meta>
< meta http-equiv =Content-Type
content =text / html; charset = ISO-8859-15/>
< h:outputStylesheet library =cssname =prime_styles.css/>
< h:outputScript library =jsname =prime_translations.js/>
< / h:头>

< h:body>
< ui:insert name =metadata/>
< ui:insert name =general_logged_user>
< div align =right>
< span style =color:#B22222; padding:3px;> < h:outputText
value =#{loggedBean._Login}/>
< / span> < span style =color:#FFA54F; padding:3px;> < h:outputText
value =Auth Method:#{loggedBean._Usuario._CUser._AuthenticationMethod}/>
< / span>
< / div>
< / ui:insert>
< f:view locale =#{localeBean.locale}>
< ui:insert name =general_settings>
< p:ajaxStatus style =width:0px; height:0px; id =ajaxStatusPanel
styleClass =spinner_ajax_loading>

< h:graphicImage value =/ resources / images / loading.gif/>
< / f:facet>

< f:facet name =complete>
< h:outputText value =/>
< / f:facet>
< / p:ajaxStatus>
< / ui:insert>

listener =#{navigationManagerSystem.initialize}/>


< h:panelGroup>
< ui:insert name =general_header>
< ui:include src =/ components / header.xhtml/>
< / ui:insert>
< h:panelGroup id =menuNavegacionPanel>

< h:form>
< h:panelGroup id =navigationPanel
rendered =#{navigationManagerSystem._ShowNavegacion}>
< h:panelGroup
rendered =#{!navigationManager._DisableNavigationButtons}>
< p:工具栏>
< p:toolbarGroup>
< ui:repeat value =#{navigationManagerSystem._Navegables}
var =item>
< p:button value =#{item._Title}
outcome =#{item._NavigationResult}>
< f:param name =NavIndexvalue =#{item._QueueIndex}/>
< / p:按钮>
< / ui:repeat>
< p:button disabled =true
value =#{navigationManagerSystem._Navegable._Title}/>
< / p:toolbarGroup>
< / p:toolbar>
< / h:panelGroup>

< / h:panelGroup>
< / h:表格>
< / h:panelGroup>
< ui:insert name =general_content>
< ui:include src =/ system / content.xhtml/>
< / ui:insert>

< / h:panelGroup>
< ui:insert name =general_footer>

< ui:include src =/ components / general_footer.xhtml/>

< / ui:insert>
< / f:view>

< / h:body>



我的文件,正在重建的bean和侦听器方法不被调用。我把过滤器放在我的 web.xml 中。另外,如果我改变我的表单,并将其设置为 enctype =multipart / form-data,因为我在文档中阅读,我无法避免的问题,在这种情况下,即使当我点击取消按钮时,再次重建。这是我的bean代码,其中 SystemNavegable 是一个抽象类:

  SuppressWarnings(serial)
@ManagedBean
@ViewScoped
public class NavegableMassiveUserAdd extends SystemNavegable {
$ b $ / **
* Field记录器。
* /
保护最终日志记录器= LogFactory.getLog(this.getClass());

/ **
* NavegableMassiveUserAdd的构造函数。
* /
public NavegableMassiveUserAdd(){
super();
this.set_Title(FacesUtils.getBundle(BundleNames.BUNDLE_SYSTEM_MENU,
BundleKeys.SYSTEM_NAVEGABLE_ADD_USERS,Añadirusuarios));
this.set_TitleDescription(FacesUtils.getBundle(BundleNames.BUNDLE_SYSTEM_MENU,
BundleKeys.SYSTEM_NAVEGABLE_ADD_USERS_DESCRIPTION,Añadirusuarios));
this.set_NavigationResult(NavigationResults.MASSIVE_USER_ADD);
this._Behaviour = NavegableBehaviour.ADD;
}
/ **
*方法actionCancelAdd。
*
* @return
* /
public String actionCancelAdd(){
return this._NavigationManagerSystem.cancelNavegable();
}

/ **
* Escuchador del evento上传。
*
*
*
* @param event
* FileUploadEvent
* @throws IOException
* @throws java.io.IOException
* /
public void listener(FileUploadEvent event)throws IOException {
UploadedFile uploadItem = event.getFile();
//更多代码
}

任何建议?提前致谢。

EDITED



更多测试完成后,我发现文件上传监听器的方法是永远不会到达的,这与我给后台bean的范围无关。我有以下依赖关系:

 < dependency> 
< groupId> commons-fileupload< / groupId>
< artifactId> commons-fileupload< / artifactId>
< version> 1.2.1< / version>
< /依赖>
<依赖>
< groupId> commons-io< / groupId>
< artifactId> commons-io< / artifactId>
< version> 1.3.2< / version>
< /依赖>

我怀疑问题可能是另一个过滤器与上传组件相冲突, 正如此处所述。不管是什么问题,当上传文件时,我的bean的initialize方法会被再次调用,并且 FacesContext.getCurrentInstance()。isPostback()带有false。

解决方案

经过几次头脑风暴,我发现这是一个过滤器问题。由于上传过滤器与 PrettyFaces 过滤器冲突,因此我必须将其添加到我的网站。 xml

 < filter-mapping> 
< filter-name> PrimeFaces FileUpload Filter< / filter-name>
< servlet-name> Faces Servlet< / servlet-name>
< dispatcher> FORWARD< / dispatcher>
< / filter-mapping>

非常感谢@Reinaldo de Carvalho的回应

https://stackoverflow.com/a/9086137/1199132


I've inserted a <p:fileUpload /> component into my JSF 2.1.5 application. I'm using PrimeFaces 3.4.1. This component is backed by a @ViewScoped bean. I have my form in this way:

<?xml version='1.0' encoding='UTF-8' ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
template="/templates/general_template.xhtml">

<ui:define name="metadata">
    <f:metadata>

        <f:viewParam id="NavIndex" name="NavIndex"
            value="#{navegableMassiveUserAdd._QueueIndex}" />
        <f:event type="preRenderView"
            listener="#{navegableMassiveUserAdd.initialize}" />
    </f:metadata>
</ui:define>

<ui:define name="general_content">
    <h:form>

        <p:fileUpload
            fileUploadListener="#{navegableMassiveUserAdd.listener}"
            mode="advanced" allowTypes="/(\.|\/)(xls|csv)$/"
            label="#{msg.SELECT}" multiple="false" />

        <p:commandButton id="cancelButton"
            action="#{navegableMassiveUserAdd.actionCancelAdd}"
            value="#{msg.CANCELAR}" ajax="false" style="margin: 9px 0px 5px;" />
    </h:form>
</ui:define>

Here it is my main template:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">


<h:head>
    <meta http-equiv="Pragma" CONTENT="no-cache"></meta>
    <meta http-equiv="cache-control" content="no-cache"></meta>
    <meta http-equiv="Expires" CONTENT="-1"></meta>
    <meta http-equiv="Content-Type"
        content="text/html; charset=ISO-8859-15" />
    <h:outputStylesheet library="css" name="prime_styles.css" />
    <h:outputScript library="js" name="prime_translations.js" />
</h:head>

<h:body>
    <ui:insert name="metadata" />
    <ui:insert name="general_logged_user">
        <div align="right">
            <span style="color: #B22222; padding: 3px;"> <h:outputText
                    value="#{loggedBean._Login}" />
            </span> <span style="color: #FFA54F; padding: 3px;"> <h:outputText
                    value="Auth Method: #{loggedBean._Usuario._CUser._AuthenticationMethod}" />
            </span>
        </div>
    </ui:insert>
    <f:view locale="#{localeBean.locale}">
        <ui:insert name="general_settings">
            <f:loadBundle basename="resources.system.bundles.Messages" var="msg" />
            <p:ajaxStatus style="width:0px;height:0px;" id="ajaxStatusPanel"
                styleClass="spinner_ajax_loading">

                <f:facet name="start">
                    <h:graphicImage value="/resources/images/loading.gif" />
                </f:facet>

                <f:facet name="complete">
                    <h:outputText value="" />
                </f:facet>
            </p:ajaxStatus>
            <p:growl id="messages" autoUpdate="true" />
        </ui:insert>

        <f:event type="preRenderView"
            listener="#{navigationManagerSystem.initialize}" />


        <h:panelGroup>
            <ui:insert name="general_header">
                <ui:include src="/components/header.xhtml" />
            </ui:insert>
            <h:panelGroup id="menuNavegacionPanel">

                <h:form>
                    <h:panelGroup id="navigationPanel"
                        rendered="#{navigationManagerSystem._ShowNavegacion}">
                        <h:panelGroup
                            rendered="#{!navigationManager._DisableNavigationButtons}">
                            <p:toolbar>
                                <p:toolbarGroup>
                                    <ui:repeat value="#{navigationManagerSystem._Navegables}"
                                        var="item">
                                        <p:button value="#{item._Title}"
                                            outcome="#{item._NavigationResult}">
                                            <f:param name="NavIndex" value="#{item._QueueIndex}" />
                                        </p:button>
                                    </ui:repeat>
                                    <p:button disabled="true"
                                        value="#{navigationManagerSystem._Navegable._Title}" />
                                </p:toolbarGroup>
                            </p:toolbar>
                        </h:panelGroup>

                    </h:panelGroup>
                </h:form>
            </h:panelGroup>
            <ui:insert name="general_content">
                <ui:include src="/system/content.xhtml" />
            </ui:insert>

        </h:panelGroup>
        <ui:insert name="general_footer">

            <ui:include src="/components/general_footer.xhtml" />

        </ui:insert>
    </f:view>

</h:body>

With that, when I upload my file, the bean is being rebuilt and the listener method not being called. I have the filters put in my web.xml. Also if I change my form and set it as enctype="multipart/form-data", as I read in documentation, I can't avoid the problem and the bean is rebuilt again, in this case even when I click on the cancel button. That's my bean code, where SystemNavegable is an abstract class:

@SuppressWarnings("serial")
@ManagedBean
@ViewScoped
public class NavegableMassiveUserAdd extends SystemNavegable {

/**
 * Field logger.
 */
protected final Log logger = LogFactory.getLog(this.getClass());

/**
 * Constructor for NavegableMassiveUserAdd.
 */
public NavegableMassiveUserAdd() {
    super();
    this.set_Title(FacesUtils.getBundle(BundleNames.BUNDLE_SYSTEM_MENU,
            BundleKeys.SYSTEM_NAVEGABLE_ADD_USERS, "Añadir usuarios"));
    this.set_TitleDescription(FacesUtils.getBundle(BundleNames.BUNDLE_SYSTEM_MENU,
            BundleKeys.SYSTEM_NAVEGABLE_ADD_USERS_DESCRIPTION, "Añadir usuarios"));
    this.set_NavigationResult(NavigationResults.MASSIVE_USER_ADD);
    this._Behaviour = NavegableBehaviour.ADD;
}
/**
 * Method actionCancelAdd.
 * 
 * @return
 */
public String actionCancelAdd() {
    return this._NavigationManagerSystem.cancelNavegable();
}

/**
 * Escuchador del evento Upload.
 * 
 * 
 * 
 * @param event
 *            FileUploadEvent
 * @throws IOException
 * @throws java.io.IOException
 */
public void listener(FileUploadEvent event) throws IOException {
    UploadedFile uploadItem = event.getFile();
    //More code
    }

Any suggestion? Thanks in advance.

EDITED

More tests done and I found that the file upload listener method is never reached, it doesn't matter which Scope I give to the backing bean. I have following dependencies included:

<dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>

And I suspect the problem can be there's another filter conflicting with the one I have for the upload component, as is told here. Whatever the problem is, my bean's initialize method is being called again when file is uploaded and FacesContext.getCurrentInstance().isPostback() comes with false.

解决方案

After several brainstorming, I found it's a filter problem. Because of upload filters are in conflict with PrettyFaces filters, I had to add this to my web.xml:

<filter-mapping>
   <filter-name>PrimeFaces FileUpload Filter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>

Many thanks @Reinaldo de Carvalho for this response

https://stackoverflow.com/a/9086137/1199132

这篇关于当使用PrettyFaces调用FileUploadListener时,ViewScoped bean被重建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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