FacesConverter 为空(JSF 2.3、CDI 2.0)
FacesConverter is null (JSF 2.3, CDI 2.0)
我尝试设置 FacesConverter 以通过 JSF 规范中引用的 JSF 页面显示某些实体。
我是运行以下的人:
- Open Liberty 19.0.0.11(也在19.0.0.6上测试过,别问我为什么是这个版本,我随便选了一个)
- Java 打开 JDK 13
-JSF 2.3
- CDI 2.0
我已将以下内容添加到我的项目中 web.xml:
<web-app id="WebApp_ID" version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>TestConverterInjection</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>
*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
以下面孔-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
version="2.3">
</faces-config>
以下beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all"
version="2.0">
</beans>
我有一个 AppConfig class,用 @FacesConfig(Version.JSF_2_3) 注释。目前一切正常。
我将简单的 TestConverter 注释如下:
@FacesConverter(value = "testConverter", managed = true)
查看 BeanManager 时,我的 TestConverter 似乎可用,因为它出现在列表中。
我的 test.xhtml 文件如下所示:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputText value="#{testBean.selectedEntity.id}">
</h:outputText>
<br/>
<h:outputText value="#{testBean.selectedEntity}" converter="testConverter">
</h:outputText>
</html>
还有我的支持 bean:
package com.test.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.util.AnnotationLiteral;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import com.test.entities.MyEntity;
@Named("testBean")
@ViewScoped
public class TestBean implements Serializable {
private List<MyEntity> listEntities;
private MyEntity selectedEntity;
@Inject private BeanManager beanManager;
@PostConstruct
public void init() {
this.listEntities = new ArrayList<MyEntity>();
for(int i = 0; i < 5; i++) {
this.listEntities.add(new MyEntity(i, "test_"+i, i+"_test"));
}
this.selectedEntity = this.listEntities.get(0);
Set<Bean<?>> beans = beanManager.getBeans(Object.class,new AnnotationLiteral<Any>() {});
for (Bean<?> bean : beans) {
System.out.println("bean: "+bean.getBeanClass().getName());
}
}
public List<MyEntity> getListEntities() {
return listEntities;
}
public void setListEntities(List<MyEntity> listEntities) {
this.listEntities = listEntities;
}
public MyEntity getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity(MyEntity selectedEntity) {
this.selectedEntity = selectedEntity;
}
}
应该没问题吧?嗯,至少它适用于 Apache TomEE 8.0.0 PluME。但是在 Open Liberty 上,我得到:
SRVE0777E: Exception émise par la classe d'application 'javax.faces.webapp.FacesServlet.service:236'
javax.servlet.ServletException:
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:236)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255)
at [internal classes]
Caused by: java.lang.NullPointerException:
at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:62)
... 1 more
因此,看起来我的 bean 已实例化但为空...Open Liberty 的功能是 javaee8-0(以确保没有遗漏任何东西)。在上面的例子中,如果我在我的转换器中删除 "managed = true",它就可以工作。 CDI 中的一些错误?
我调查了这个问题,发现它是由 beanManager.getBeans 调用引起的。该 bean 已在 beanManger 中注册(如您所演示的),但未正确检索。由于 Converter 使用泛型,您需要按类型而不是 class 进行搜索。我在 MyFaces 社区中打开了一个问题并提供了一个补丁! :)
https://issues.apache.org/jira/browse/MYFACES-4311
修复将包含在 MyFaces 2.3.7 中。
感谢您发现这个!
我尝试设置 FacesConverter 以通过 JSF 规范中引用的 JSF 页面显示某些实体。
我是运行以下的人: - Open Liberty 19.0.0.11(也在19.0.0.6上测试过,别问我为什么是这个版本,我随便选了一个) - Java 打开 JDK 13 -JSF 2.3 - CDI 2.0
我已将以下内容添加到我的项目中 web.xml:
<web-app id="WebApp_ID" version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>TestConverterInjection</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>
*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
以下面孔-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
version="2.3">
</faces-config>
以下beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all"
version="2.0">
</beans>
我有一个 AppConfig class,用 @FacesConfig(Version.JSF_2_3) 注释。目前一切正常。
我将简单的 TestConverter 注释如下:
@FacesConverter(value = "testConverter", managed = true)
查看 BeanManager 时,我的 TestConverter 似乎可用,因为它出现在列表中。
我的 test.xhtml 文件如下所示:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputText value="#{testBean.selectedEntity.id}">
</h:outputText>
<br/>
<h:outputText value="#{testBean.selectedEntity}" converter="testConverter">
</h:outputText>
</html>
还有我的支持 bean:
package com.test.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.util.AnnotationLiteral;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import com.test.entities.MyEntity;
@Named("testBean")
@ViewScoped
public class TestBean implements Serializable {
private List<MyEntity> listEntities;
private MyEntity selectedEntity;
@Inject private BeanManager beanManager;
@PostConstruct
public void init() {
this.listEntities = new ArrayList<MyEntity>();
for(int i = 0; i < 5; i++) {
this.listEntities.add(new MyEntity(i, "test_"+i, i+"_test"));
}
this.selectedEntity = this.listEntities.get(0);
Set<Bean<?>> beans = beanManager.getBeans(Object.class,new AnnotationLiteral<Any>() {});
for (Bean<?> bean : beans) {
System.out.println("bean: "+bean.getBeanClass().getName());
}
}
public List<MyEntity> getListEntities() {
return listEntities;
}
public void setListEntities(List<MyEntity> listEntities) {
this.listEntities = listEntities;
}
public MyEntity getSelectedEntity() {
return selectedEntity;
}
public void setSelectedEntity(MyEntity selectedEntity) {
this.selectedEntity = selectedEntity;
}
}
应该没问题吧?嗯,至少它适用于 Apache TomEE 8.0.0 PluME。但是在 Open Liberty 上,我得到:
SRVE0777E: Exception émise par la classe d'application 'javax.faces.webapp.FacesServlet.service:236' javax.servlet.ServletException: at javax.faces.webapp.FacesServlet.service(FacesServlet.java:236) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255) at [internal classes] Caused by: java.lang.NullPointerException: at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:62) ... 1 more
因此,看起来我的 bean 已实例化但为空...Open Liberty 的功能是 javaee8-0(以确保没有遗漏任何东西)。在上面的例子中,如果我在我的转换器中删除 "managed = true",它就可以工作。 CDI 中的一些错误?
我调查了这个问题,发现它是由 beanManager.getBeans 调用引起的。该 bean 已在 beanManger 中注册(如您所演示的),但未正确检索。由于 Converter 使用泛型,您需要按类型而不是 class 进行搜索。我在 MyFaces 社区中打开了一个问题并提供了一个补丁! :)
https://issues.apache.org/jira/browse/MYFACES-4311
修复将包含在 MyFaces 2.3.7 中。
感谢您发现这个!