如何引用 JAR 文件中提供的 JSF 托管 bean?

Posted

技术标签:

【中文标题】如何引用 JAR 文件中提供的 JSF 托管 bean?【英文标题】:How to reference JSF managed beans which are provided in a JAR file? 【发布时间】:2011-12-01 14:31:20 【问题描述】:

我有一个结构如下的 WAR 文件:

JSF 托管 bean BusinessObjectTypeListController 位于 /WEB-INF/lib 中的 commons-web-1.0.jar 中,并在 BusinessObjectTypeListView.xhtml 中引用。当我运行我的 Web 应用程序并调用该视图时,我收到以下错误:

javax.servlet.ServletException: /view/common/businessObjectTypeListView.xhtml @34,94 listener="#businessObjectTypeListController.selectData": 目标不可达,标识符“businessObjectTypeListController”解析为空

为什么找不到控制器类?它应该在类路径中,是吗?

【问题讨论】:

你是如何运行应用程序的?您是否只是从 Eclipse 中选择“在服务器上运行”?还是您手动部署到容器?这是哪个容器? 我使用 ant 将它部署到 Glassfish 中。 【参考方案1】:

您需要在 commons-web-1.0.jar 文件中包含一个符合 JSF 2.0 的 /META-INF/faces-config.xml 文件,以便让 JSF 扫描 JAR 文件以查找带有 JSF 注释(如 @ManagedBean)的类并自动注册它们。

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    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-facesconfig_2_0.xsd"
    version="2.0">
</faces-config>

JSF 不会扫描类路径中每个 JAR 文件的每个类,那样会太昂贵。只会扫描带有上述/META-INF/faces-config.xml 文件的 JAR。

您还应该确保您在 webapp 自己的 /WEB-INF/faces-config.xml 文件的 &lt;faces-config&gt; 声明中具有 metadata-complete="true" 属性,否则 JSF 将假定此面孔配置是完整的,因此不会自动扫描 JAR 文件中的注释。

如果这些条件都不满足(或不能满足),那么您需要在 webapp 自己的 /WEB-INF/faces-config.xml 中手动将 bean 注册为 &lt;managed-bean&gt;,而不是依赖注解。

另请参阅JSF 2.0 specification 的第 11.4.2 章(重点是我的)。

11.4.2 应用程序启动行为

...

该算法为组装基于 JSF 的 Web 组件的开发人员提供了相当大的灵活性 应用。例如,一个应用程序可能包含一个或多个自定义 UIComponent 实现,以及 关联的渲染器,因此它可以在名为“/WEB-INF/faces-config.xml”的应用程序资源中声明它们 无需以编程方式将它们注册到 Application 实例。此外,应用程序可能会选择 包含一个包含“META-INF/faces-config.xml”资源的组件库(打包为 JAR 文件)。 此资源的存在导致组件、渲染器和其他 JSF 实现类存储在此 库 JAR 文件自动注册,应用程序无需任何操作。

【讨论】:

这对于更现代的 JSF 版本是否仍然足够?我正在尝试帮助***.com/questions/59742677/… 并阅读 SO 中的许多“重复”(对于许多链接到此处,许多应标记为重复)。可能还需要 web-fragment.xml 吗?在我尝试复制问题之前先问一下。 @Kukeltje 是的。链接问题中的问题很可能是由于网络片段库放置不正确引起的。它们属于 WAR/WEB-INF/lib 而不是 EAR/lib。【参考方案2】:

就我而言,CDI bean 也有同样的问题。

我有 common.jar 项目,我在其中放置了 CDI bean。 (没有 beans.xml) 和 我有 webapp.war,它的 lib 和 beans.xml 中包含 common.jar。

当我从 jsf 调用 cdi bean 时,我得到它不可访问异常:/

项目结构是使用 maven 创建的: - common.jar 的 maven-archetype-quickstart - 用于 webapp.war 的 maven-archetype-webapp

我正在使用 eclipse/juno 部署到 Glassfish 3.1.x。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

已解决: 对于 EJB 和 JAR 打包,您应该将 beans.xml 放在 src/main/resources/META-INF/ 中。 对于 WAR 打包,您应该将 beans.xml 放在 src/main/webapp/WEB-INF/ 中。 请记住,只有 .java 文件应该放在 src/main/java 和 src/test/java 目录中。 .xml 文件之类的资源应该在 src/main/resources 中。

来自主题: CDI: beans.xml, where do I put you?

【讨论】:

【参考方案3】:

在我看来,BusinessObjectTypeListController 类是正确创建的,但没有实例化。

如何在视图上创建类的实例?如果您使用 BeanFactory,请查看配置 xml 文件

【讨论】:

以上是关于如何引用 JAR 文件中提供的 JSF 托管 bean?的主要内容,如果未能解决你的问题,请参考以下文章

导入的 JSF 项目缺少用户库 JAR

Spring JSF 集成:如何在 JSF 托管 bean 中注入 Spring 组件/服务?

如何以编程方式注册 JSF 托管 bean?

将 JSF 托管 bean 迁移到 CDI 托管 bean

如何将 JSF 托管 bean 属性传递给 JavaScript 函数?

在任何 Servlet 相关类中按名称获取 JSF 托管 bean