1

我将一些 facelets 自定义组件迁移到适当的复合组件中,但在呈现包含复合组件的视图时遇到以下错误:

javax.faces.view.facelets.TagException: /WEB-INF/taglib/cctest.xhtml @15,26 <composite:interface> Component Not Found for identifier: bodyId.getParent().
  at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:135)
  at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)
  at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
  at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
  at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
  at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:320)
  at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:379)
  at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:326)
  at com.sun.faces.facelets.tag.UserTagHandler.apply(UserTagHandler.java:142)
  at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
  at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:187)
  at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
  at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
  at com.sun.faces.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:188)
  at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
  at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
  at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
  at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:164)
  at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:906)
  at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.jav

在错误消息中,名称bodyId指的是<h:body>下面文件中的 id,并且getParent()在创建异常消息期间是硬编码的。@15,26<composite:interface>在cctest.xhtml下面的结尾。

这是包含复合组件的页面:

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

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
  xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"
  xmlns:bam="http://bam.mycompany.com/jsftaglib" 
>

<f:view locale="en" id="viewId">
  <h:head id="headId">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Title</title>
  </h:head>
  <h:body id="bodyId">
    <bam:cctest value="hello world."/>
  </h:body>
</f:view>
</html>

这是cctest.xhtml声明复合组件的文件cctest

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

<html xmlns="http://www.w3.org/1999/xhtml" 
  xmlns:composite="http://java.sun.com/jsf/composite"
  xmlns:h="http://java.sun.com/jsf/html"
  >

  <h:head>
    <title>not used</title>
  </h:head>

  <h:body>
    <composite:interface>
      <composite:attribute name="value" required="true"/>
    </composite:interface>

    <composite:implementation>
      <h:outputText id="text_#{cc.attrs.value}" value="#{cc.attrs.value}"/>
    </composite:implementation>
  </h:body>

</html>

复合组件在名为 bam.taglib.xml 的文件中声明,该文件位于 /WEB-INF/taglib/ 中,位于cctext.xhtml. 这是文件:

<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
  version="2.0">

  <namespace>http://bam.mycompany.com/jsftaglib</namespace>

  <tag>
    <tag-name>cctest</tag-name>
    <source>cctest.xhtml</source>
  </tag>

</facelet-taglib>

我在 tomcat 7.0.41 中使用 mojarra 2.1.21。我的 faces-config.xml 文件是空的,没有托管 bean 或其他自定义组件(验证器等)。Web.xml 只声明了一些上下文参数,以及映射在 *.xhtml 上的 faces servlet;以下是那些上下文参数:

  • javax.faces.FACELETS_REFRESH_PERIOD = 1
  • javax.faces.FACELETS_SKIP_COMMENTS = false
  • javax.faces.FACELETS_LIBRARIES = /WEB-INF/taglib/bam.taglib.xml
  • javax.faces.PROJECT_STAGE = 开发
  • javax.faces.VALIDATE_EMPTY_FIELDS = false
  • javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = true

查看 facelets 错误页面中显示的组件树,没有名为 的元素bodyId,这可能是我的问题的提示。其副本如下所示:

<UIViewRoot id="j_id1" inView="true" locale="en" renderKitId="HTML_BASIC" rendered="true" transient="false" viewId="/pages/composite_component_test.xhtml">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <UIOutput id="headId" inView="true" rendered="true" transient="false">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>Title</title>
  </UIOutput>
</UIViewRoot>

非常感谢您查看此问题。

4

1 回答 1

3

当通过包含引用另一个组件的组件时,我已经看到在开发模式下发生这种类型的错误,例如

<composite:implementation>
    <ui:include src="/resources/mycomponents/component1.xhtml" />
</composite:implementation>

相反,应该使用适当的 JSF 组件引用语法

例如

<mycomponents:component1/>

奇怪的是,如果切换到生产模式并且一切正常,则不会发生此错误。

于 2015-12-20T16:36:47.463 回答