我有一个具有明确定义的界面的应用程序。它使用 CDI 来解析模块(具体来说,它使用 API 接口上的 Instance 注入点来解析模块),并通过接口毫无问题地来回传递各种数据。我故意将 API 和实现分开,模块仅从 API 继承以避免紧密耦合,应用程序仅通过运行时依赖关系了解模块,并通过 API 完成数据传递。应用程序无需模块即可正常运行,只需将 jar 放入 WEB-INF/lib 文件夹并重新启动应用程序服务器即可添加模块。
我遇到的问题是我希望模块创建视图的一部分,因此我想以可移植的方式调用 JSF 组件,或者从模块中包含以获得它呈现其视图。我已经解决了我想要调用的模块,并且已经准备好对该模块接口的引用。我最初想到的方法是执行 ui:include ,要求模块提供视图模板的位置,但我不知道如何以有意义的方式回答该查询,因为视图解析是从应用程序完成的根,而不是库根。
执行摘要是,我不知道如何使用 JSF for .xhtml(模板/组件)文件从应用程序跳转到库。
使用 CC 会很好,但如何指定在运行时需要特定的 CC 实例,而不是将其硬编码到页面中?
我当然可以直接调用应用程序代码并要求它提供标记,但这看起来确实很暴力,而且一旦我有了标记,我不确定如何告诉 JSF 对其进行评估。也就是说,我可以想象一个组件将采用资源路径,获取标记并对其进行评估,返回完整的标记,我只是不知道如何实现它。
如果可能的话,我宁愿避免强迫模块开发人员采用重型 UIComponent 方法,这意味着要么采用动态方式执行 ui:include (或某种等效方式),要么采用动态方式调用 CC。 (我不介意在应用程序中编写一次 UIComponent 方法,如果这样可以让模块开发人员的生活更轻松)
关于我应该在哪里解决这个问题有什么建议吗? (如果我先找到答案,我会在这里发布答案)
我知道你的问题基本上可以归结为如何将 Facelets 视图包含在 JAR 中?
您可以通过放置自定义来做到这一点ResourceResolver在 JAR 中。
public class FaceletsResourceResolver extends ResourceResolver {
private ResourceResolver parent;
private String basePath;
public FaceletsResourceResolver(ResourceResolver parent) {
this.parent = parent;
this.basePath = "/META-INF/resources"; // TODO: Make configureable?
}
@Override
public URL resolveUrl(String path) {
URL url = parent.resolveUrl(path); // Resolves from WAR.
if (url == null) {
url = getClass().getResource(basePath + path); // Resolves from JAR.
}
return url;
}
}
在 webapp 中配置它web.xml
如下:
<context-param>
<param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
<param-value>com.example.FaceletsResourceResolver</param-value>
</context-param>
想象一下你有一个/META-INF/resources/foo/bar.xhtml
in random.jar
,那么你可以按照通常的方式包含它
<ui:include src="/foo/bar.xhtml" />
甚至动态地
<ui:include src="#{bean.path}" />
注意:从 Servlet 3.0 和更新的 JBoss/JSF 2.0 版本开始,整个ResourceResolver
如果您将文件保存在/META-INF/resources
文件夹。以上ResourceResolver
仅在 Servlet 2.5 或更早的 JBoss/JSF 版本中是强制性的,因为它们在META-INF
资源解析。
也可以看看:
- 将 Facelets 文件(模板、包含、复合)打包到 JAR 中
- JSF Facelets 模板打包
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)