【问题标题】:Composite component folder structure复合组件文件夹结构
【发布时间】:2014-03-03 17:02:42
【问题描述】:

JSF 规范 2.2 (2013-03-20) 在第 10.3.3.1 项(声明用于 Facelet 页面的复合组件库)中说:

如果在 XHTML 页面中声明了 facelet 标记库,其命名空间以字符串开头 “http://java.sun.com/jsf/composite/”(不带引号),命名空间声明的其余部分 被视为资源库的名称 [...]

如果“http://java.sun.com/jsf/composite/”后面的子字符串包含“/”字符,或任何对于库名称不合法的字符,则必须采取以下操作。如果 application.getProjectStage() 是 Development,则必须在页面中放置一条信息性错误消息并进行记录。否则必须只记录该消息。

这意味着拥有以下文件夹结构是非法的:

resources
    components
        system
        something_specific
        something_even_more_specific

并引用库名称“http://java.sun.com/jsf/composite/components/something_specific”?这是正确的吗?

这似乎是一个奇怪的限制。我希望我的资源是结构化的,而不是一大堆。

这种分层库实际上可以在 Wildfly 8.0.0.CR1 中使用,但我不确定依赖这种行为是否明智。

欢迎提供“最佳实践”类型的答案。

【问题讨论】:

  • javax.faces.application.ResourceHandler.createResource(String) javadoc 中偶然发现以下内容:For historical reasons, this method operate correctly when the argument resourceName is of the form libraryName/resourceName, even when resourceName contains '/' characters.

标签: jsf-2 composite-component


【解决方案1】:

我会总结一下我的发现。

来源:JSF spec issue 740discussion preceding issue 740another discussionJSF spec issue 1141discussion preceding issue 1141

库名称中不允许使用斜线。资源名称中允许使用斜杠。

实际上,Mojarra 2.2.5 复合组件库既可以在 XHTML 命名空间声明中工作,也可以在 taglib 的 <composite-library-name>components/system</composite-library-name> 中工作。我希望这在未来的 Mojarra 和/或 JSF 规范版本中仍然会中断。如果您使用它,您将受到 JSF 规范/实现开发人员的摆布。相关问题和讨论表明他们愿意保留向后兼容性,即使是针对非预期功能。

在 MyFaces 中有一个特殊设置,org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME (MyFaces issue 3454)。我希望依靠名称中带有斜杠的资源库,使用此设置可能会破坏某些功能,例如 JSF 资源版本控制(它如何知道哪个部分是库名称以及哪个部分属于资源名称?)。

我认为复合组件库层次结构可以通过在一个taglib中一个一个地导入组件来实现:

<tag>
    <tag-name>test</tag-name>
    <component>
      <resource-id>
          components/system/test.xhtml
      </resource-id>
    </component>
</tag>

因此,库名称实际上变成了“组件”,而资源名称变成了“system/test.xhtml”。

更新:您需要一个 hack 才能使用 Mojarra。

/**
 * Allows nesting composite components deeper. E.g.:
 * <resource-id>system/components/package/anotherpackage/test.xhtml</resource-id>
 *
 * To structure your sources better. To document your components and their attributes in
 * taglib.xml for IDE content assist.
 *
 * So it purposefully violates the resource lookup algorithm described in JSF 2.2,
 * 2.6.1.3 Resource Identifiers.
 */
public class NestedCCResourceHandler extends ResourceHandlerWrapper {

    public NestedCCResourceHandler(final ResourceHandler resourceHandler) {
        super(resourceHandler);
    }

    @Override
    public Resource createResourceFromId(String resourceId) {
        // just treat the whole thing as resourceName, no libraries
        Resource resource = super.createResource(resourceId);
        // com.sun.faces.component.CompositeComponentStackManager#findCompositeComponentUsingLocation
        // expects to find libraryName in the resource path, so set it to empty string
        resource.setLibraryName("");
        return resource;
    }

}

并在 faces-config.xml 中注册:

<application>
    <resource-handler>fully.qualified.name.NestedCCResourceHandler</resource-handler>
</application>

这可能会破坏 CC 的库,也许是版本合同?不确定,很久以前做的。绝对适用于 Mojarra 2.3.3.SP1。

【讨论】:

  • I think composite component library hierarchy may be implemented by importing components in a taglib one by one - 我测试过这个吗?不适用于 Mojarra 2.2.12 - 它需要 test.xhtlm 作为资源名称和 system 作为库名称,完全抛弃 components。见com.sun.faces.facelets.tag.AbstractTagLibrary.CompositeComponentTagFactory.createHandler(TagConfig)。这可以通过自定义 TagLibrary 或 ResourceHandler 来解决。
【解决方案2】:

经过一些实验,我认为应该阅读这些陈述:

  • 命名空间声明的其余部分被视为资源库的名称 http://java.sun.com/jsf/composite/components/system 必须匹配 /resources/components/system

  • 库名中任何不合法的字符

    如果您声明http://java.sun.com/jsf/composite/components/system2/resources/components/system2 不存在,请采取措施

    Warning: This page calls for XML namespace http://java.sun.com/jsf/composite/components/system2 declared with prefix y but no taglibrary exists for that namespace.

所以声明是绝对合法的

xmlns:x="http://java.sun.com/jsf/composite/components/system"

以及 /resources 下存在的任何其他文件夹结构

【讨论】:

  • 嗯,我不明白你回答的要点。首先,您建议分解文件夹结构?这正是我不想做的。在“资源”文件夹中也有静态资源,如图像、样式、脚本。所以我希望“资源”下第一级的文件夹是“组件”和“静态”。而且“资源”下肯定会有2级以上的文件夹。例如,“组件/系统/对话框”。我不想分解这个结构并在一个级别上创建所有文件夹,例如“components-system-dialogs”。
  • 其次,我不明白在 taglib 中导入会发生什么变化。带有斜线的复合组件库名称仍然是非法的,无论是在 XHTML 页面中还是在 taglib 定义中使用。
  • 感谢您的坚持。所以你是说斜杠限制仅适用于通过http://java.sun.com/jsf/composite/ 直接在XHTML 中使用复合组件命名空间时?还有一个小问题:为什么我不应该使用/resources/components 文件夹? components 部分不是特殊的保留名称,它相当于您的my-cc
  • 如果没有阅读第一版答案,您的答案的第一段会令人困惑且无法理解。尝试写出他们自己清楚的答案,而不考虑其他/以前的答案,甚至不考虑 cmet。
  • @this 在我之前的回答中,我认为引用意味着您必须遵循在 jar 中声明复合组件的相同模式。仔细阅读,不是这个意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多