请求范围内的托管 Bean 保持创建

发布于 2025-01-01 04:14:52 字数 5961 浏览 2 评论 0原文

我正在应对这种奇怪的情况。我有 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,

感谢您的宝贵时间,并对我的英语不好表示歉意

!页面 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中:(。有什么想法可以防止这种奇怪的行为吗?

There is this strange situation I'm fighting on. I have 3 pages, les call them A, B and C. Every page has its own Managed Bean in request scope: MB1, MB2 and MB3, respectively. When I enter on A, MB1 is created. From A, I call a window.showModalDialog to open B and every time B its opened MB2 is created. The strangeness starts when I call page C from B with window.showModalDialog, and MB3 gets created once. This behavior is driving me insane, because I have done things like this and its the first time this is happening.

I must also say that MB1 and MB2 have the @KeepAlive annotation (similar to use the a4j:keepAlive tag component, and MB3 is a clean managed bean.

I'm open to any ideas to solve the problem. I'm currently working with JSF 1.2, RichFaces 3.3.3 and JBoss EAP 5.1.

Thanks for your time and sorry for my bad english!

EDIT 1: The source code for pages A, B and C:

page 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>

page 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>

page C (a simple jsf page which does nothing):

<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>

If you need anything else to check the problem, just ask for it and I'll post it as soon as I can. By te way, sorry for not write anything in the last 8 hours I was sleeping =(.

EDIT 2: I have reviewed this issue in other web explorers, and the result was that the problem it only appears in the spiteful IE8 :(. Any ideas what to do to prevent this odd behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丑疤怪 2025-01-08 04:14:52

在网上冲浪后,我发现这篇文章对我有帮助。我遵循了该配置,现在我的页面 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>

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" 时,一切都开始正常工作。

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

After surfing in the web, I found this article which helped me. I followed that configuration and now my pages A, B and C works.

EDIT: My problem was just an IE 8 configuration. But there was another issue on a PageXBean with the RichFaces 3.3.3 @KeepAlive tag. When I opened pageX.jsp with the showDialog js function, the first time it worked nice, but from the second onwards it showed an error and the managed bean constructor was not even called. This was driving me insane because there was no clue about it, until my co-worker gave with the point. I'll show you the problem in depth:

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>

Bean class:

@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...
}

So, at first fiew there was no problem, BUT the thing was that the value of CLASS_X was the same as the managed bean:

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

This was the root of our problems. When he changed the value to CLASS_X = "pageX2" everything started to work normally.

Hope this helps anyone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文