菜单奇怪的渲染行为

发布于 2024-12-27 20:02:08 字数 5213 浏览 3 评论 0原文

抱歉这篇文章的长度,但目前我们一无所知,所以我希望发布尽可能多的细节。
我们在 Internet Explorer 9 上的 primefaces 2.2 菜单中遇到问题。 我们使用eclipse来开发web应用,服务器是tomcat,版本6.0.18,由于客户要求无法升级。我们在战争中包含了所有必需的库,这也是客户的要求。下面是我们在应用程序 web-inf/lib 文件夹中包含的库的(详尽)列表:

  • Primefaces 2.2.1
  • antlr 2.7.6
  • commons-collections 3.1
  • commons-fileupload 1.2.1
  • commons-io 1.4
  • dom4j 1.6.1
  • hibernate jpa 2.0 api 1.0.0 最终
  • 休眠 3
  • itext-xtra 5.1.3
  • itextpdf 5.1.3
  • javassist 3.12.0 ga
  • jsf-api Mojarra JSF API 实现 2.1.1 (20110408-​​FCS)
  • jsf-impl (如上所述,已通过阅读清单进行验证)
  • jstl 1.2
  • jta 1.1
  • log4j 1.2.15
  • redmond 1.0。 1
  • slf4j-api 1.6.1
  • slf4j-log4j12-1.6.4
  • xmlworker - 1.1.1
  • commons-email 1.2

到目前为止,我们已经在三种不同的场景下测试了该应用程序:

  1. 开发环境:localhost tomcat 6.0.18、eclipse、ie9、http
  2. 部署的应用程序:tomcat 6.0.18、 https - TAM(ibm tivoli sso 系统),ie9
  3. 已部署应用程序:tomcat 6.0.18、https - TAM(ibm tivoli sso 系统)、firefox 9

菜单包含三个根菜单“新请求”、“正在进行的工作”和“管理”。
对于情况1.和2.(涉及ie9),第二个菜单“正在进行中”消失并在导航期间重新出现(单击其他菜单,单击重定向按钮,...),其他两个菜单仍然可见。我们无法找到规则,也无法系统地复制这种行为。 正如您从下面的代码中看到的,我们对子菜单设置器进行了注释,以检查是否存在将其设置为不同内容的编程错误。
对于 Firefox,这种情况永远不会发生,它工作得很好。 最后,只有在情况 2(ie9 + https over tam)中,我们有时会遇到 servlet 渲染异常,到目前为止,我们得到了以下内容:

  • javax.servlet.ServletException: javax.servlet.jsp.JspException: java.lang.IllegalStateException: Parent不为 null,但此组件不相关
  • javax.servlet.ServletException:菜单栏必须位于表单元素内
  • ArrayIndexOutOfBounds

primefaces 菜单的行为奇怪的是,它是由代码构建的,并且它的支持 bean 有一个会话范围,下面列出了相关代码。
那么这是一个库问题吗?浏览器问题?我们的应用程序的错误? 有人可以建议一些测试来缩小问题范围或提供一些工具来获得一些提示吗?
主容器页面是:

<h:body>
<h:form id="masterForm">
    <p:growl id="msg" life="10000" showDetail="true" sticky="false" />
</h:form>
<p:layout fullPage="true">
    <p:layoutUnit position="top" height="90" id="layUnitNorth"
        resizable="false" closable="false" collapsible="false"  
        scrollable="null" zindex="199">
        <ui:insert name="header">
            <div id="userInfoPanel">
                <ui:include src="userinfo.xhtml" />
            </div>              
            <ui:include src="menu.xhtml" /> 
        </ui:insert>
    </p:layoutUnit>

    <p:layoutUnit position="center" scrollable="true">
        <ui:insert name="content">
            <p:layoutUnit position="center">
            </p:layoutUnit>
        </ui:insert>
    </p:layoutUnit>
</p:layout>

菜单页面是:

<ui:composition>
<h:form id="menuForm">
    <p:menubar effect="slide" styleClass="menuCustom">
        <p:submenu label="New" >
            <p:menuitem value="new requests" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=0');" />
            <p:menuitem value="channel 1" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=1');" />
            <p:menuitem value="channel 2" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=2');" />
            <p:menuitem value="channel 3" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=3');" />
        </p:submenu>
        <p:submenu label="work in progress"
            binding="#{menuCtrl.boxSubMenu}">
        </p:submenu>
        <p:submenu label="administration" rendered="#{userInfo.admin}">
            <p:menuitem value="Customers" url="#" />
            <p:menuitem value="Templates" url="#" />
            <p:menuitem value="Digital signature" url="#" />
        </p:submenu>
    </p:menubar>
</h:form>

menuCtrl 是一个会话 bean:

public class MenuCtrl {

final static Logger log = Logger.getLogger(MenuCtrl.class);

private Submenu boxSubMenu;

public void setBoxSubMenu(Submenu boxSubMenu) {
    //this.boxSubMenu = boxSubMenu;
}

public Submenu getBoxSubMenu() {
    return boxSubMenu;
}

public MenuCtrl() {
    try {
        boxSubMenu = BoxMenuHelper.getBoxSubMenu();
    } catch (Exception ex) {            
        String msg = "Impossibile creare il menu di navigazione nei box";
        log.error(msg, ex);
        showMessage(FacesMessage.SEVERITY_ERROR, msg);
    }
}

}

子菜单工厂方法:

    public static Submenu getBoxSubMenu() throws Exception{
    CatalogazioneRepository br = new CatalogazioneRepository();
    Submenu sm = new Submenu();
    try {
        for (Catalogazione box : br.getOnlyBoxes()) {
            MenuItem item = new MenuItem();
            item.setId("boxMenuItem" + box.getId());
            item.setValue(box.getNome());
            item.setOnclick("navigateTo('Box/ListaRichieste.xhtml?box="+ box.getId() +"');");
            sm.getChildren().add(item);
        }
        return sm;
    } catch (Exception ex) {
        String msg = "Errore durante la creazione del menu di navigazione nei box";
        log.error(msg, ex);
        throw new Exception(msg, ex);
    }
}

Sorry for the length of this post, but at the moment we are clueless, so i wish to post as many details as possible.
We are experiencing a problem with primefaces 2.2 menu on internet explorer 9.
We use eclipse to develop the web application, the server is a tomcat, version 6.0.18, and can't be upgraded due to customer requirements. We include all the required libraries inside the war, this is a customer requirement too. Below there's the (exhaustive) list of libraries we include in the application web-inf/lib folder :

  • Primefaces 2.2.1
  • antlr 2.7.6
  • commons-collections 3.1
  • commons-fileupload 1.2.1
  • commons-io 1.4
  • dom4j 1.6.1
  • hibernate jpa 2.0 api 1.0.0 final
  • hibernate 3
  • itext-xtra 5.1.3
  • itextpdf 5.1.3
  • javassist 3.12.0 ga
  • jsf-api Mojarra JSF API Implementation 2.1.1 (20110408-FCS)
  • jsf-impl (as above, verified reading the manifest)
  • jstl 1.2
  • jta 1.1
  • log4j 1.2.15
  • redmond 1.0.1
  • slf4j-api 1.6.1
  • slf4j-log4j12-1.6.4
  • xmlworker - 1.1.1
  • commons-email 1.2

Till now we have tested the application on three different secenarios:

  1. Development environment : localhost tomcat 6.0.18,eclipse, ie9, http
  2. Deployed application : tomcat 6.0.18, https - TAM (a ibm tivoli sso system), ie9
  3. Deployed application : tomcat 6.0.18, https - TAM (a ibm tivoli sso system), firefox 9

the menu contains three root menus "new requests","work in progress" and "administration".
For both cases 1. and 2. (involve ie9), the second menu "work in progress" disappears and reapears during navigation (clicking on other menus, clicking redirect buttons,...) , the other two remain visible. We haven't been able to find a rule nor to replicate the behaviour systematically.
As you can see from the below code we have commented the submenu setter to check there weren't some programming bug that set it to something different.
With Firefox it never happens, it works fine.
Finally, only in case 2 (ie9 + https over tam), we got sometimes servlet rendering exceptions, till now we have got the following :

  • javax.servlet.ServletException: javax.servlet.jsp.JspException: java.lang.IllegalStateException: Parent was not null, but this component not related
  • javax.servlet.ServletException: Menubar must be inside a form element
  • ArrayIndexOutOfBounds

the primefaces menu which behaves weirdly gets built by code and its backing bean has a session scope, the relevant code is listed below.
So is this a library problem? a browser problem? A bug of our application ?
Can someone suggest some test to narrow the problem or a tool to get some hints?
the main container page is :

<h:body>
<h:form id="masterForm">
    <p:growl id="msg" life="10000" showDetail="true" sticky="false" />
</h:form>
<p:layout fullPage="true">
    <p:layoutUnit position="top" height="90" id="layUnitNorth"
        resizable="false" closable="false" collapsible="false"  
        scrollable="null" zindex="199">
        <ui:insert name="header">
            <div id="userInfoPanel">
                <ui:include src="userinfo.xhtml" />
            </div>              
            <ui:include src="menu.xhtml" /> 
        </ui:insert>
    </p:layoutUnit>

    <p:layoutUnit position="center" scrollable="true">
        <ui:insert name="content">
            <p:layoutUnit position="center">
            </p:layoutUnit>
        </ui:insert>
    </p:layoutUnit>
</p:layout>

the menu page is :

<ui:composition>
<h:form id="menuForm">
    <p:menubar effect="slide" styleClass="menuCustom">
        <p:submenu label="New" >
            <p:menuitem value="new requests" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=0');" />
            <p:menuitem value="channel 1" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=1');" />
            <p:menuitem value="channel 2" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=2');" />
            <p:menuitem value="channel 3" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=3');" />
        </p:submenu>
        <p:submenu label="work in progress"
            binding="#{menuCtrl.boxSubMenu}">
        </p:submenu>
        <p:submenu label="administration" rendered="#{userInfo.admin}">
            <p:menuitem value="Customers" url="#" />
            <p:menuitem value="Templates" url="#" />
            <p:menuitem value="Digital signature" url="#" />
        </p:submenu>
    </p:menubar>
</h:form>

the menuCtrl is a session bean:

public class MenuCtrl {

final static Logger log = Logger.getLogger(MenuCtrl.class);

private Submenu boxSubMenu;

public void setBoxSubMenu(Submenu boxSubMenu) {
    //this.boxSubMenu = boxSubMenu;
}

public Submenu getBoxSubMenu() {
    return boxSubMenu;
}

public MenuCtrl() {
    try {
        boxSubMenu = BoxMenuHelper.getBoxSubMenu();
    } catch (Exception ex) {            
        String msg = "Impossibile creare il menu di navigazione nei box";
        log.error(msg, ex);
        showMessage(FacesMessage.SEVERITY_ERROR, msg);
    }
}

}

the submenu factory method:

    public static Submenu getBoxSubMenu() throws Exception{
    CatalogazioneRepository br = new CatalogazioneRepository();
    Submenu sm = new Submenu();
    try {
        for (Catalogazione box : br.getOnlyBoxes()) {
            MenuItem item = new MenuItem();
            item.setId("boxMenuItem" + box.getId());
            item.setValue(box.getNome());
            item.setOnclick("navigateTo('Box/ListaRichieste.xhtml?box="+ box.getId() +"');");
            sm.getChildren().add(item);
        }
        return sm;
    } catch (Exception ex) {
        String msg = "Errore durante la creazione del menu di navigazione nei box";
        log.error(msg, ex);
        throw new Exception(msg, ex);
    }
}

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

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

发布评论

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

评论(2

夜唯美灬不弃 2025-01-03 20:02:08

我发现这个 Primefaces 论坛帖子

他们(optimus.prime - the PrimeFaces 的创建者(Oleg 是论坛的高级用户)声称您应该将 menuitem 的构建器放在请求范围内,以避免奇怪的行为。

I found this Primefaces forum post

They (optimus.prime - the creator of PrimeFaces, and Oleg a very advanced user of the forum) claims that you should put the builder of the menuitem in request scope, to avoid strange behaviour.

暗喜 2025-01-03 20:02:08

这篇文章有点旧,但是,如果您有这样的用法,请更喜欢属性;
- 结果
- url

下面的用法可能仅适用于客户端操作上非常特殊的 java 脚本需求:

    <p:menuitem value="new requests" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=0');" />

首选以下选项:

    <p:menuitem value="new requests" url="Richieste/ListaRichieste.xhtml?canale=0"/>

    <p:menuitem value="new requests" outcome="Richieste/ListaRichieste?canale=0" />

This post is a bit old but, if you have a usage like this, prefer the attributes;
- outcome
- url

This usage below may only be needed for very special java script needs on client-side operations:

    <p:menuitem value="new requests" onclick="navigateTo('Richieste/ListaRichieste.xhtml?canale=0');" />

Prefer below options:

    <p:menuitem value="new requests" url="Richieste/ListaRichieste.xhtml?canale=0"/>

or

    <p:menuitem value="new requests" outcome="Richieste/ListaRichieste?canale=0" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文