【问题标题】:Managed Bean in Request Scope keeps created请求范围内的托管 Bean 不断创建
【发布时间】:2012-02-24 16:03:33
【问题描述】:

我正在与这种奇怪的情况作斗争。我有 3 个页面,分别称为 A、B 和 C。每个页面在请求范围内都有自己的托管 Bean:分别为 MB1、MB2 和 MB3。当我在 A 上输入时,会创建 MB1。从 A 中,我调用一个 window.showModalDialog 来打开 B,并且每次 B 创建其打开的 MB2。当我使用 window.showModalDialog 从 B 调用页面 C 并且 MB3 被创建一次时,奇怪就开始了。这种行为让我发疯,因为我做过这样的事情,而且这是第一次发生。

我还必须说MB1和MB2都有@KeepAlive注解(类似于使用a4j:keepAlive标签组件,而MB3是一个干净的托管bean。

我愿意接受任何解决问题的想法。我目前正在使用 JSF 1.2、RichFaces 3.3.3 和 JBoss EAP 5.1。

感谢您的宝贵时间,抱歉我的英语不好!

编辑 1:A、B 和 C 页的源代码:

A页:

<!-- The js function which calls page B -->
<script type="text/javascript">
function buscaDeposito() {
    var blnResultado = false;
    var sUrl = 'pageB.jsf';
    var oDatos = new Object();
    var args = 'dialogHeight: 450px; dialogWidth: 700px; edge: Raised; center: Yes; help: No; resizable: No; status: No';
    if (window.showModalDialog(sUrl, oDatos, args)) {
        blnResultado = true;
        document.getElementById('frmFormaCobroLiqDocCartera:txtNroDeposito').value = oDatos.ReturnValue;
    }
    return blnResultado;
}
</script>
<!-- HTML/JSF fragment of page A -->
<table class="tabla" width="100%">
    <tr>
        <td style="width: 25%; text-align: right">
            <h:outputText>Nro. de depósito no identificado</h:outputText>
        </td>
        <td style="width: 20%">
            <h:inputText id="txtNroDeposito" styleClass="inputText" style="width: 100%"
                readonly="true"
                value="#{formaCobroLiqDocCartera.numeroDepositoNoIdentificado}" />
        </td>
        <td>
            <a4j:commandLink id="lnkBuscaDNIDeposito"
                onclick="if (!buscaDeposito()) return false;"
                action="#{formaCobroLiqDocCartera.cargaDatosDeposito}"
                reRender="pnlDeposito" limitToList="true">
                <h:graphicImage value="/Resource/iconos/buscar-con-ayuda.png"
                    styleClass="pic" title="Buscar" />
            </a4j:commandLink>
        </td>
    </tr>
</table>

B页:

<script type="text/javascript">
    window.returnValue = false;
    // The js function which calls pageC
    function veDetalleDeposito() {
        //The function depositoSeleccionado checks if at least one 
        //radio button has been selected in the dataTable.
        if (!depositoSeleccionado()) {
            alert('Debe seleccionar un depósito.');
        } else {
            var sUrl = 'pageC.jsf';
            var oDatos = new Object();
            var args = 'dialogHeight: 280px; dialogWidth: 400px; edge: Raised; center: Yes; help: No; resizable: No; status: No';
            window.showModalDialog(sUrl, oDatos, args);
        }
    }
</script>
<!-- The call to pageC in the oncomplete javascript because I must set a session
    variable with the value of the selected row. -->
<a4j:commandLink id="lnkVeDetalle" oncomplete="veDetalleDeposito()">
    <h:graphicImage value="/Resource/iconos/visualizar-registro.png" styleClass="pic"
        title="Ver detalle de depósito" />
</a4j:commandLink>
<rich:dataTable id="dtDepositos" width="100%" headerClass="cabeceraDataTable"
    binding="#{listaDepositoNoIdentificado.hdtDepositos}" rows="15"
    value="#{listaDepositoNoIdentificado.lstDepositos}" var="deposito">
    <rich:column width="5%" style="text-align:center">
        <f:facet name="header">
            <h:outputText value="Seleccione" />
        </f:facet>
        <h:selectOneRadio onclick="dataTableSelectOneRadio(this)"
            valueChangeListener="#{listaDepositoNoIdentificado.setSelectedItem}">
            <f:selectItem itemValue="null" />
        </h:selectOneRadio>
    </rich:column>
    <!-- more columns here... -->
</rich:dataTable>

页面 C(一个什么都不做的简单 jsf 页面):

<h:form style="font-family: sans-serif;">
    <h2 class="tituloPagina">Detalle del Depósito No Identificado</h2>
    <fieldset>
        <legend class="legenda">Detalle del Depósito No Identificado</legend>
        <table>
            <tr>
                <td>Tipo:</td>
                <td>
                    <h:outputText value="#{detalleDeposito.deposito.tipo}" />
                </td>
            </tr>
            <tr>
                <td>Número:</td>
                <td>
                    <h:outputText value="#{detalleDeposito.deposito.codigoDni}" />
                </td>
            </tr>
            <!-- more data to present to the users. -->
        </table>
    </fieldset>
</h:form>

faces-config.xml:

<managed-bean>
    <managed-bean-name>formaCobroLiqDocCartera</managed-bean-name>
    <managed-bean-class>com.abaco.presentacion.managedbean.PFormaCobroLiqDocCartera</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
    <managed-bean-name>listaDepositoNoIdentificado</managed-bean-name>
    <managed-bean-class>com.abaco.presentacion.managedbean.PListaDepositoNoIdentificado</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
    <managed-bean-name>detalleDeposito</managed-bean-name>
    <managed-bean-class>com.abaco.presentacion.managedbean.PDetalleDeposito</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

如果您需要其他任何内容来检查问题,请提出要求,我会尽快发布。顺便说一句,很抱歉在我睡觉的最后 8 个小时里没有写任何东西 =(.

编辑 2:我已经在其他网络浏览器中查看过这个问题,结果是它只出现在恶意的 IE8 中:(。有什么想法可以防止这种奇怪的行为吗?

【问题讨论】:

  • 可以分享源代码吗?
  • 你怎么知道MB3只创建一次?
  • @prajeeshkumar 因为当我转到第 3 页时,它显示了相同的信息。在 MB3 的构造函数中,我添加了这个逻辑以从 MB2 中设置的会话变量中获取一些数据。另外,当我选择一个单选按钮并且在 pageB 显示 pageC 或被此按钮关闭之前,我在 MB2 中更改了此会话变量 Select(未在 pageB 代码中发布)并返回到 MB1,其中信息显示正确。

标签: java jsf richfaces jsf-1.2


【解决方案1】:

在网上冲浪后,我找到了this article,这对我有帮助。我遵循了那个配置,现在我的页面 A、B 和 C 可以工作了。

编辑:我的问题只是 IE 8 配置。但是在带有 RichFaces 3.3.3 @KeepAlive 标记的 PageXBean 上还有另一个问题。当我使用 showDialog js 函数打开 pageX.jsp 时,第一次运行良好,但从第二次开始,它显示错误,甚至没有调用托管 bean 构造函数。这让我发疯,因为没有任何线索,直到我的同事给出了这一点。我会深入地向你展示这个问题:

faces-config.xml:

<managed-bean>
    <managed-bean-name>pageX</managed-bean-name>
    <managed-bean-class>com.abaco.presentacion.managedbean.PageXBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

豆类:

@KeepAlive(ajaxOnly=false)
public class PageXBean {
    //some attributes...
    public PageXBean() {
        ClassX oClassX = new ClassX();
        //set data into oClassX ...
        try {
            FacesContext objFC = FacesContext.getCurrentInstance();
            Object request = objFC.getExternalContext().getRequest();
            HttpServletRequest objServletRequest = (HttpServletRequest)request;
            HttpSession objSesion = objServletRequest.getSession();
            objSesion.setAttribute(UConstants.SessionVars.CLASS_X, oClassX);
        } catch (Exception objEx) {
            System.out.println("Problema al registrar variable de sesión: " +
                objEx.getMessage());
      }
    }
    //more methods and stuff...
}

所以,乍一看没有问题,但问题是 CLASS_X 的值与托管 bean 相同:

public class UConstants {
    public static class SessionVars {
        public static String CLASS_X = "pageX";
    }
}

这是我们问题的根源。当他将值更改为CLASS_X = "pageX2" 时,一切都开始正常工作了。

希望这对任何人都有帮助。

【讨论】:

  • 它将如何为所有其他网站访问者解决问题?您是否要显示一些警告消息,告知他们必须更改浏览器设置才能使您的网站正常运行?
  • @BalusC 很抱歉在这么长时间之后编辑我的问题。浏览器中没有警告,只是奇怪的行为,但它是 IE8 配置。我描述了一个主要问题和解决方案。
猜你喜欢
  • 2019-12-01
  • 2017-09-06
  • 2013-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-28
  • 2012-12-29
  • 1970-01-01
相关资源
最近更新 更多