Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何创建模块化JSF2.0应用程序?_Java_Jsf 2_Cdi_Jboss Weld_Modular - Fatal编程技术网

Java 如何创建模块化JSF2.0应用程序?

Java 如何创建模块化JSF2.0应用程序?,java,jsf-2,cdi,jboss-weld,modular,Java,Jsf 2,Cdi,Jboss Weld,Modular,我有一个定义良好的接口应用程序。它使用CDI来解析模块(具体地说,它使用API接口上的实例注入点来解析模块),并通过接口将各种数据传回第四方,而不会出现问题。我有意将API和实现分开,模块仅从API继承以避免紧密耦合,应用程序仅通过运行时依赖性知道模块,并通过API完成数据传递。应用程序在没有模块的情况下运行良好,只需将jar放入WEB-INF/lib文件夹并重新启动应用服务器即可添加模块 我遇到的问题是,我希望模块创建视图的一部分,因此我希望以可移植的方式调用JSF组件,或者从模块中执行inc

我有一个定义良好的接口应用程序。它使用CDI来解析模块(具体地说,它使用API接口上的实例注入点来解析模块),并通过接口将各种数据传回第四方,而不会出现问题。我有意将API和实现分开,模块仅从API继承以避免紧密耦合,应用程序仅通过运行时依赖性知道模块,并通过API完成数据传递。应用程序在没有模块的情况下运行良好,只需将jar放入WEB-INF/lib文件夹并重新启动应用服务器即可添加模块

我遇到的问题是,我希望模块创建视图的一部分,因此我希望以可移植的方式调用JSF组件,或者从模块中执行include,以使其呈现视图。我已经解决了要调用的模块,并准备好了对模块接口的引用。我最初认为这样做的方式是做一个ui:include,它要求模块提供其视图模板的位置,但我不知道如何以有意义的方式回答该查询,因为视图解析是从应用程序根而不是库根进行的

执行摘要是,我不知道如何使用JSF for.xhtml(模板/组件)文件跨越应用程序与库之间的鸿沟

使用CC会很好,但是如何指定在运行时需要一个特定的CC实例,而不是将其硬编码到页面中

当然,我可以直接调用应用程序代码并要求它进行标记,但这似乎真的很残酷,一旦我有了标记,我就不知道如何确切地告诉JSF对其进行评估。这就是说,我可以想象一个组件将获取资源路径,获取标记并对其求值,返回完成的标记,我只是不知道如何实现它

如果可能的话,我宁愿避免强迫模块开发人员采用重型UIComponent方法,这意味着要么采用动态方式进行ui:include(或某些等效方式),要么采用动态方式调用CCs。(我不介意在应用程序中编写一次UIComponent方法,如果这是使模块开发人员的生活更轻松的必要条件)


有没有关于我应该在哪里找到答案的建议?(如果我先找到答案,我会在这里发布)

我知道你的问题基本上可以归结为如何在JAR中包含Facelets视图

您可以通过在JAR中放置一个自定义项来实现这一点

公共类FaceletsResourceResolver扩展了ResourceResolver{
私有资源解析器父级;
私有字符串基路径;
公共FaceletsResourceResolver(资源解析程序父级){
this.parent=parent;
this.basePath=“/META-INF/resources”;//TODO:使可配置?
}
@凌驾
公共URL解析URL(字符串路径){
URL URL=parent.resolveUrl(路径);//从WAR解析。
如果(url==null){
url=getClass().getResource(basePath+path);//从JAR解析。
}
返回url;
}
}
在webapp的
web.xml
中进行如下配置:


javax.faces.FACELETS\u资源\u解析器
com.example.FaceletsResourceResolver
假设您在
random.jar
中有一个
/META-INF/resources/foo/bar.xhtml
,那么您可以按照通常的方式包含它


甚至是动态的


注意:由于Servlet 3.0和更新的JBoss/JSF 2.0版本,如果您将文件保存在
/META-INF/resources
文件夹中,则不需要使用整个
ResourceResolver
方法。上述
resourcesolver
仅在Servlet2.5或更早版本的JBoss/JSF中是必需的,因为它们在
META-INF
资源解析中存在错误

另见:

我在寻找关于同一主题的信息时,发现了这个链接:它对我来说非常有效。

顺便说一句。。当您使用seam焊料(目前正在集成到apache deltaspike中)时,您可以避免实现自己的资源解析器,这是一个非常有用的库,可以补充CDI(您典型的Java EE 6组件模型)

我也在jsf应用程序中尝试了模块化。基本上,我构建了一个带有工具栏的模板界面,其中充满了每个模块提供的按钮。通常,您将通过提供一个字符串列表作为命名对象来完成此操作:

@Produces
@SomethingScoped
@Named("topMenuItems")
public List<String> getTopMenuItems(){
return Arrays.asList("/button1.xhtml", "/button2.xhtml", "/button3.xhtml");
}
现在,您可以使用菜单栏中的按钮更改面板中显示的视图,这样您就可以在不重新加载页面的情况下进行导航

一些建议(或“我所学到的”):

  • 您可能需要为getTopMenuItems方法选择一个较大的范围
  • 不要嵌套ui:include标记。不幸的是,这是不可能的(例如,您的view1.xhtml不能包含其他合成)。我真的 希望这样的事情是可能的,因为你可以真正建立 模块化jsf视图与此类似,有点像没有 Portlet=D
  • 执行ui:include-in-container组件(如TabView)也有问题
  • 通常不建议混合使用JSTL(c:forEach)和JSF。但我发现这是作为ui:repeat-get工作的唯一方法 评估太晚,例如,未显示您包含的内容

  • 多好的问题啊!一个我对自己感兴趣的人。我希望有人有一个好的答案可以分享。@maple_shaft这是否回答了您的问题,或者我是否需要打开一个关于构建模块化JSF 2.0应用程序的社区wiki?在这一点上,这对我来说是非常直接的,但这并不意味着它对每个阅读本文的人都是如此。是的,这对我来说是非常有意义的。在我当前项目结束后的一段时间里,我计划重构公共模块,以便在未来的应用程序中重用,我想知道如何
    ....
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    ....
    <xy:toolbar>
      <xy:toolbarGroup>
        <c:forEach items="#{topMenuItems}" var="link">
          <ui:include src="#{link}" />
        </c:forEach>
      </xy:toolbarGroup>
    </xy:toolbar>
    <xy:panel>
      <ui:include src="#{contentPath}"/>
    </xy:panel>
    
    <ui:composition ...>
        <xy:commandButton actionListener="#{topMenuController.switchContent()}"
            value="Test" id="testbutton" />
    </ui:composition>
    
    public void switchContent(){
        contentPath = "/view1.xhtml";
    }
    
    @Produces
    @SomethingScoped
    @Named("contentPath")
    public String getContentPath(){
        return contentPath;
    }