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

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

问题描述

我已将 <p:fileUpload/> 组件插入到我的 JSF 2.1.5 应用程序中.我正在使用 PrimeFaces 3.4.1.该组件由 @ViewScoped bean 支持.我的表格是这样的:

<ui:define name="元数据"><f:元数据><f:viewParam id="NavIndex" name="NavIndex"value="#{navegableMassiveUserAdd._QueueIndex}"/><f:event type="preRenderView"listener="#{navegableMassiveUserAdd.initialize}"/></f:元数据></ui:define><ui:define name="general_content"><h:形式><p:文件上传fileUploadListener="#{navegableMassiveUserAdd.listener}"mode="高级" 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>

这是我的主要模板:

<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:头><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="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:输出文本value="#{loggedBean._Login}"/></span><span style="color: #FFA54F; padding: 3px;"><h:输出文本value="身份验证方法:#{loggedBean._Usuario._CUser._AuthenticationMethod}"/></span>

</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="开始"><h:graphicImage value="/resources/images/loading.gif"/></f:facet><f:facet name="完整"><h:outputText value=""/></f:facet></p:ajaxStatus><p:growl id="messages" autoUpdate="true"/></ui:insert><f:event type="preRenderView"listener="#{navigationManagerSystem.initialize}"/><h:面板组><ui:insert name="general_header"><ui:include src="/components/header.xhtml"/></ui:insert><h:panelGroup id="menuNavegacionPanel"><h:形式><h:panelGroup id="navigationPanel"渲染="#{navigationManagerSystem._ShowNavegacion}"><h:面板组render="#{!navigationManager._DisableNavigationButtons}"><p:工具栏><p:工具栏组><ui:repeat value="#{navigationManagerSystem._Navegables}"var="项目"><p:button value="#{item._Title}"结果="#{item._NavigationResult}"><f:param name="NavIndex" value="#{item._QueueIndex}"/></p:按钮></ui:repeat><p:button disabled="true"value="#{navigationManagerSystem._Navegable._Title}"/></p:toolbarGroup></p:工具栏></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>

这样,当我上传我的文件时,bean 正在重建并且 listener 方法没有被调用.我将过滤器放在了我的 web.xml 中.此外,如果我更改表单并将其设置为 enctype="multipart/form-data",正如我在文档中所读到的那样,我无法避免该问题并且 bean 将再次重建,在这种情况下即使我点击取消按钮.这是我的 bean 代码,其中 SystemNavegable 是一个抽象类:

@SuppressWarnings("serial")@ManagedBean@ViewScoped公共类 NavegableMassiveUserAdd 扩展 SystemNavegable {/*** 现场记录器.*/受保护的最终日志记录器 = LogFactory.getLog(this.getClass());/*** NavegableMassiveUserAdd 的构造函数.*/公共 NavegableMassiveUserAdd() {极好的();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;}/*** 方法 actionCancelAdd.** @返回*/公共字符串 actionCancelAdd() {返回 this._NavigationManagerSystem.cancelNavegable();}/*** Escuchador del evento 上传.**** @param 事件* 文件上传事件* @throws IOException* @throws java.io.IOException*/公共无效侦听器(FileUploadEvent 事件)抛出 IOException {UploadedFile uploadItem = event.getFile();//更多代码}

有什么建议吗?提前致谢.

已编辑

完成了更多测试,我发现文件上传侦听器方法从未达到过,我给支持 bean 的范围无关紧要.我包括以下依赖项:

<依赖><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 过滤器冲突,我不得不将其添加到我的 web.xml 文件中.xml:

<filter-name>PrimeFaces 文件上传过滤器</filter-name><servlet-name>Faces Servlet</servlet-name><调度员>前进</调度员></过滤器映射>

非常感谢@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天全站免登陆