我有两个项目结构略有不同的演示项目。一个生成 WAR 存档,另一个生成 EAR 存档。
在 WAR 项目中,在 Backingbeans 中注入
@EJB
、@FacesConverter
和 @FacesValidator
按预期工作。
在 EAR 项目中,注入仅适用于 Backingbean,但不适用于
@FacesConverter
或 @FacesValidator
(尽管所有三个类都在同一文件夹/jar 中)。 @PostConstruct
在 @FacesConverter
和 @FacesValidator
中也不起作用(但在 BackingBean 中),所以我肯定错过了一些重要的东西。但什么?
我检查/复制了
web.xml
、faces-config.xml
和 beans.xml
它们是相同的。 beans.xml
位于 WAR 项目中的 WEB-INF
下,以及 EAR 项目的 ejb 模块中的 META-INF
下。
@FacesConverter
和 @FacesValidator
标有 managed=true
,因此 CDI 应该可以工作。
默认情况下,我使用的是 Payara,但我也在 WildFly 上测试过,情况是一样的(Mojarra 4.0.7)。
我增加了一些
...webcontainer.jsf...
类的日志级别,但我没有看到任何错误或警告。
@FacesConverter(managed = true, value = "demoConverter")
public class DemoConverter implements Converter<DemoEntity>, Serializable {
...
@EJB
DemoRemote bean;
int i;
...
@PostConstruct
public void init() {i=42;}
@Override
public DemoEntity getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
...
logger.info("[ (bean=" + bean + ") (i="+i+")] "); <-- bean always null and i=0!!!
...
}
...
}
CDI 不兼容 EAR。如果您的 EAR 包含多个 WAR,则某些 CDI 功能只能在其中一个 WAR 中工作。
只要您想使用 CDI,就坚持使用 WAR。如果您打算在多个 WAR 之间共享 Web 工件(托管 Bean、faces 转换器、facelets 模板、Web 资源等),请将它们放入所谓的 Web 片段 JAR 文件中。可以在具有共享代码的多个 JSF 项目的结构中找到指南。这些 Web 片段 JAR 文件的真实示例是 OmniFaces 和 PrimeFaces。