【问题标题】:FacesConverter is null (JSF 2.3, CDI 2.0)FacesConverter 为空(JSF 2.3、CDI 2.0)
【发布时间】:2020-03-08 13:20:06
【问题描述】:

我尝试设置 FacesConverter 以通过我的 JSF 页面显示某些实体,如 JSF 规范中所引用的。

我正在运行以下命令: - 打开 Liberty 19.0.0.11(也在 19.0.0.6 上测试过,不要问我为什么是这个版本,我随机选择了另一个) - Java Open 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>

下面的faces-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 类,用 @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>

还有我的支持豆:

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: 应用程序“javax.faces.webapp.FacesServlet.service:236”出现异常 javax.servlet.ServletException: 在 javax.faces.webapp.FacesServlet.service(FacesServlet.java:236) 在 com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255) 在[内部课程] 引起:java.lang.NullPointerException: 在 org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsString(FacesConverterCDIWrapper.java:62) ... 1 更多

所以,看起来我的 bean 已实例化但为空... Open Liberty 的功能是 javaee8-0(以确保没有任何遗漏)。在上面的示例中,如果我在转换器中删除“managed = true”,它就可以工作。 CDI 中的一些错误?

【问题讨论】:

  • “所以,看起来我的 bean 已实例化,但为空......” 这在终端上是矛盾的。如果它被实例化,它不能为空。 ;-) 我在上一个问题中看到过这个managed="true"。我会试着找到它,但你也可以。
  • 没有找到重复的(还)但请阅读showcase.omnifaces.org/cdi/FacesConverter
  • 你查看日志看jsf是否真的在2.3模式下运行?并且您可以调试代码 jsf 代码以查看它实际上是如何解析的。还将 facelets 命名空间更改为 jsf 2.2+ 的命名空间(很可能是题外话,但绝不会更少)
  • 使用 MyFaces 2.3.5 和 OpenwebBeans 2.0.12 当 managedtrue 时,我得到相同的 NPE。使用 Mojarra 2.3.9 我得到了我的转换器实例(而不是包装器)并且没有 NPE,但 @Injected 字段仍保留在转换器中的 null 中。
  • 这确实是矛盾的。根据最近的 jsf2.3 jsr,转换器和验证器中的注入现在应该可以工作了:arjan-tijms.omnifaces.org/p/jsf-23.html?m=1。但是,这不是重点,重点是转换器本身在注入页面时为空。通过删除 managed=true,我设法在一个带有哑转换器的测试项目上工作。但是,在这种特定情况下,它没有。

标签: cdi myfaces open-liberty jsf-2.3


【解决方案1】:

我调查了这个问题,发现它是由 beanManager.getBeans 调用引起的。 bean 已在 beanManger 中注册(如您所演示的),但它只是没有正确检索。由于 Converter 使用泛型,因此您需要按类型而不是类进行搜索。我在 MyFaces 社区中打开了一个问题并提供了一个补丁! :)

https://issues.apache.org/jira/browse/MYFACES-4311

该修复将包含在 MyFaces 2.3.7 中。

感谢您发现这个!

【讨论】:

    猜你喜欢
    • 2011-11-18
    • 2018-11-16
    • 2018-10-10
    • 2023-04-07
    • 1970-01-01
    • 2021-10-29
    • 2015-07-13
    • 2015-11-11
    相关资源
    最近更新 更多