如何引用 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
文件的 <faces-config>
声明中具有 metadata-complete="true"
属性,否则 JSF 将假定此面孔配置是完整的,因此不会自动扫描 JAR 文件中的注释。
如果这些条件都不满足(或不能满足),那么您需要在 webapp 自己的 /WEB-INF/faces-config.xml
中手动将 bean 注册为 <managed-bean>
,而不是依赖注解。
另请参阅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?的主要内容,如果未能解决你的问题,请参考以下文章
Spring JSF 集成:如何在 JSF 托管 bean 中注入 Spring 组件/服务?