【问题标题】:JSF 2.0 - Myfaces have problems rendering composite componentsJSF 2.0 - Myfaces 在渲染复合组件时遇到问题
【发布时间】:2012-04-10 18:44:26
【问题描述】:

几天前我已将 mojarra 更改为 myfaces 以解决 this problem,现在我在渲染我的复合组件时遇到了一个奇怪的问题,它们根本没有在我第二次打开一个弹出窗口时呈现(弹出窗口是复合组件)。

第一次,正如你在 fieldset 中看到的,一切都被渲染好了:

然后我点击“CANCELAR”(取消)按钮,第二次,除了对话框,我的复合组件都没有被渲染:

当我查看日志时,我发现了这些消息:

[#|2012-04-10T15:22:00.681-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2uz|#]
[#|2012-04-10T15:22:00.684-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:inputRazaoSocial|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vi|#]
[#|2012-04-10T15:22:00.685-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vn|#]
[#|2012-04-10T15:22:00.686-0300|SEVERE|glassfish3.1.1|org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer|_ThreadID=19;_ThreadName=Thread-2;|facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component prevenda:popupPreVenda:j_id_2vs|#] 

如您所见,问题在于 myfaces 在复合组件中找不到构面... 唯一使用 facets 的复合组件是 hrgi:popup:

<c:interface>
    <c:attribute name="titulo" default="sem titulo" required="false"/>
    <c:attribute name="renderizar" default="false" required="false"/>
    <c:attribute name="modal" default="true" required="false"/>
    <c:attribute name="bordaConteudo" default="true" required="false"/>
    <c:facet name="cabecalho" required="false"/>
    <c:facet name="conteudo" required="true"/>
    <c:facet name="botoes" required="true"/>
</c:interface>

<c:implementation>
<h:outputStylesheet library="css" name="hrgiPopup.css" target="head"/>
<h:outputStylesheet library="css" name="clearfix.css" target="head"/>
<h:outputScript library="js" name="hrgiPopup.js" target="head"/>
<h:panelGroup layout="block" rendered="#{cc.attrs.renderizar}"
              class="hrgi-dialog-panel clearfix">
    <h:panelGroup layout="block" class="hrgi-dialog-overlay clearfix" rendered="#{cc.attrs.modal}"></h:panelGroup>
    <h:panelGroup id="popup" layout="block" class="hrgi-dialog-box clearfix">
        <h:panelGroup layout="block" class="hrgi-dialog-title clearfix">
            <h:outputText style="float:left" value="#{cc.attrs.titulo}"/>
        </h:panelGroup>
        <h:panelGroup layout="block" class="hrgi-dialog-content clearfix">
            <c:renderFacet name="cabecalho" required="false"/>
            <h:panelGroup layout="block" class="hrgi-dialog-background clearfix"
                          rendered="#{cc.attrs.bordaConteudo}">
                <c:renderFacet name="conteudo" required="true"/>
            </h:panelGroup>
            <h:panelGroup layout="block" class="clearfix" rendered="#{not cc.attrs.bordaConteudo}">
                <c:renderFacet name="conteudo" required="true"/>
            </h:panelGroup>
            <c:renderFacet name="botoes" required="true"/>
            <script type="text/javascript">
                cercarEventoTab("#{cc.clientId}:popup");
            </script>
        </h:panelGroup>
    </h:panelGroup>
</h:panelGroup>
</c:implementation>

这是 MyFaces 的错误吗? Mojarra 不会出现这样的问题!

更新

当用户点击“CANCELAR”按钮时就会出现问题......该操作调用此代码以清除字段并关闭对话框:

public void cancelar(ActionEvent evento){
    fechar();
    UIComponent componente=evento.getComponent().getParent().getParent().getParent();
    componente.getFacet("conteudo").getChildren().clear();
}

此代码改编自您可以看到 here 的方法。在这种情况下,仅重新创建 facet conteudo 内的组件。工作正常,除了我的复合组件。

【问题讨论】:

    标签: jsf-2 myfaces composite-component


    【解决方案1】:

    MyFaces 中的代码没问题。日志建议 org.apache.myfaces.renderkit.html.HtmlCompositeComponentRenderer 在您的复合组件文件中找不到 c:implementation 条目,从 2.1.6 开始,进行了一些更改以防止在 libraryName 中使用 '/' 字符(请参阅MYFACES-3454详情)。添加了一个 Web 配置参数 (org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME) 以启用后向行为,但请注意新行为在规范中以明确的方式提及。

    如果这不起作用,请尝试创建一个简单的演示应用程序来重现该错误并在MyFaces Issue Tracker 中创建一个问题。这样一来,它就有更好的机会在未来的版本中得到解决。

    更新

    我试图用提供的信息复制它,但没有成功。问题是调用

    componente.getFacet("conteudo").getChildren().clear();
    

    该代码删除了构面内的所有组件,而 MyFaces 足够聪明,可以记住已删除的组件。当视图恢复时,MyFaces 算法会像第一个请求一样构建视图,然后删除组件以正确恢复状态。这种行为是意料之中的,因此 MyFaces 代码中没有错误。相反,我认为前面描述的行为是 Mojarra 中的一个错误,您应该更改代码以以其他方式重置您的输入组件,可能清除 bean 内的值,或者在您的复合组件中创建一个方法表达式属性,可以当取消操作发生并清除所需的输入字段时调用。有很多方法可以做到这一点。

    【讨论】:

    • 网络配置没有帮助,可能是复合组件标签声明似乎没有错误:xmlns:hrgi="java.sun.com/jsf/composite/hrgi"。我已经添加了有问题的新信息。感谢您的关注
    • 我已经改编了“componente.getFacet("conteudo").getChildren().clear();”从您可以在这里看到的第二种方法:cwiki.apache.org/MYFACES/clear-input-components.html。有没有另一种方法可以清除我的复合组件中没有问题的页面的所有组件??
    【解决方案2】:

    我不知道为什么,但是在我创建了一些类来处理异常之后,这个问题就消失了……

    public class HRGIExceptionHandler extends ExceptionHandlerWrapper {
    
        private ExceptionHandler wrapped;
    
        public HRGIExceptionHandler(ExceptionHandler wrapped) {
            this.wrapped = wrapped;
        }
    
        @Override
        public ExceptionHandler getWrapped() {
            return wrapped;
        }
    
        @Override
        public void handle() throws FacesException {
            Iterator i = getUnhandledExceptionQueuedEvents().iterator();
            while (i.hasNext()) {
                ExceptionQueuedEvent event = (ExceptionQueuedEvent) i.next();
                ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();
                Throwable t = context.getException();
                try{
                    t.printStackTrace();
                }finally{
                    i.remove();
                }
            }
            getWrapped().handle();
        }
    }
    

    和

    public class HRGIExceptionHandlerFactory extends ExceptionHandlerFactory {
    
        private ExceptionHandlerFactory parent;
    
        public HRGIExceptionHandlerFactory(ExceptionHandlerFactory parent) {
            this.parent = parent;
        }
    
        @Override
        public ExceptionHandler getExceptionHandler() {
            ExceptionHandler result = new HRGIExceptionHandler(parent.getExceptionHandler());
            return result;
        }
    }
    

    最后我把这个添加到 faces.config 中:

    <factory>
        <exception-handler-factory>com.hrgi.web.erp.HRGIExceptionHandlerFactory</exception-handler-factory>
    </factory>
    

    【讨论】:

      猜你喜欢
      • 2011-09-28
      • 2011-03-06
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      相关资源
      最近更新 更多