Jsf 识别和解决javax.el.PropertyNotFoundException:无法访问目标

Jsf 识别和解决javax.el.PropertyNotFoundException:无法访问目标,jsf,cdi,el,managed-bean,propertynotfoundexception,Jsf,Cdi,El,Managed Bean,Propertynotfoundexception,当尝试引用EL中的托管bean时,比如so{bean.entity.property},有时会抛出javax.EL.PropertyNotFoundException:Target Unreachable异常,通常是在设置bean属性或调用bean操作时 似乎有五种不同的信息: 它们都是什么意思?它们是如何产生的,应该如何解决?1。无法访问目标,标识符“bean”解析为null 这可以归结为,在EL-like so#{bean}中,托管bean实例本身不能被该标识符(托管bean名称)

当尝试引用EL中的托管bean时,比如so
{bean.entity.property}
,有时会抛出
javax.EL.PropertyNotFoundException:Target Unreachable
异常,通常是在设置bean属性或调用bean操作时

似乎有五种不同的信息:

  • 它们都是什么意思?它们是如何产生的,应该如何解决?

    1。无法访问目标,标识符“bean”解析为null 这可以归结为,在EL-like so
    #{bean}
    中,托管bean实例本身不能被该标识符(托管bean名称)准确地找到

    确定原因可分为三个步骤:

    a。谁在管理豆子?
    B托管bean的(默认)名称是什么?
    C支持bean类在哪里

    1a。谁在管理豆子? 第一步是检查哪个bean管理框架负责管理bean实例。是通过CDICDI吗?或者它是JSFvia?或者是Springvia?您能确保在同一个支持bean类上没有混合多个bean管理框架特定的注释吗?例如
    @Named@ManagedBean
    @Named@Component
    ,或
    @ManagedBean@Component
    。这是错误的。bean必须由最多一个bean管理框架管理,并且必须正确配置该框架。如果你已经不知道该选哪一个,那就去看看吧

    如果是CDI通过
    @Named
    管理bean,那么您需要确保以下几点:

    • CDI1.0(JavaEE6)需要
      /WEB-INF/beans.xml
      文件才能在战争中启用CDI。它可以是空的,也可以只有以下内容:

      
      
    • 没有任何
      beans.xml
      ,或空的
      beans.xml
      文件,或与上述CDI 1.0兼容的
      beans.xml
      将与CDI 1.0的行为相同。当CDI 1.1兼容的
      beans.xml
      具有显式
      version=“1.1”
      ,那么默认情况下,它将只注册带有显式CDI作用域注释的
      @命名的
      bean,例如、。如果您打算将所有bean注册为CDI管理的bean,即使是没有显式CDI作用域的bean,将以下CDI 1.1兼容的
      /WEB-INF/beans.xml
      bean发现模式=“all”
      集一起使用(默认设置为
      bean发现模式=“annotated”

      
      
    • 将CDI 1.1+与
      bean discovery mode=“annotated”
      (默认值)一起使用时,请确保没有意外导入JSF作用域,例如而不是CDI作用域。注意IDE自动完成

    • 如果将Mojarra 2.3.0-2.3.2和CDI 1.1+与
      bean discovery mode=“annotated”
      (默认值)一起使用,则需要将Mojarra升级到2.3.3或更高版本,原因是出现故障。如果您无法升级,那么您需要在
      beans.xml
      中设置
      bean发现模式=“all”
      ,或者在WAR中的任意类(通常是某种应用程序范围的启动类)上放置JSF 2.3特定的
      @FacesConfig
      注释

    • 在Servlet 4.0容器上使用JSF 2.3时,如果声明了符合Servlet 4.0的
      web.xml
      ,则需要显式地将JSF 2.3特定的
      @FacesConfig
      注释放在WAR中的任意类上(通常是某种应用程序范围的启动类)。这在Servlet3.x中不是必需的

    • 像Tomcat和Jetty这样的非JavaEE容器并不附带CDI。您需要手动安装它。这比仅仅添加库JAR要多一些工作。对于Tomcat,请确保遵循此答案中的说明:

    • 您的运行时类路径是干净的,在CDIAPI相关的JAR中没有重复项。确保您没有混合使用多个CDI实现(Weld、OpenWebBeans等)。当目标容器已经打包了CDIAPI时,确保不要在webapp中提供另一个CDI甚至JavaEEAPI JAR文件

    • 如果您正在将用于JSF视图的CDI托管bean打包到JAR中,那么请确保JAR中至少有一个有效的
      /META-INF/beans.xml
      (可以保持为空)


    如果是JSF通过已弃用的
    @ManagedBean
    管理bean,并且您无法迁移到CDI,那么您需要确保以下几点:

    • faces config.xml
      根声明与JSF 2.0兼容。因此XSD文件和
      版本必须至少指定JSF2.0或更高版本,而不是1.x

      
      
      对于JSF2.1,只需将
      2_0
      2.0
      分别替换为
      2_1
      2.1

      如果您使用的是JSF2.2或更高版本,那么请确保您使用的是
      xmlns.jcp.org
      名称空间,而不是
      java.sun.com

      
      
      对于JSF2.3,只需将
      2_2
      2.2
      分别替换为
      2_3
      2.3

    • 您没有意外地导入而不是导入。注意IDE的自动完成功能,Eclipse会自动将错误的提示作为列表中的第一项

    • 您没有通过
      faces config.xml
      中的JSF 1.x样式的
      条目在同一个支持bean类上覆盖
      @ManagedBean
      ,同时使用不同的托管bean名称。这个将优先于
      @ManagedBean
      。由于JSF2.0,在
      faces config.xml
      中注册托管bean是不必要的,只需将其删除即可

    • 您的运行时类路径是cl
      <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-web-api</artifactId>
          <version>7.0</version>
          <scope>provided</scope>
          <type>jar</type>
      </dependency>
      
      <managed-bean>
        <managed-bean-name>"the name by wich your backing bean will be referenced"</managed-bean-name>
        <managed-bean-class>"your backing bean fully qualified class name"</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>    
      </managed-bean>
      
      <context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>"/WEB-INF/beans-config.xml</param-value>
      </context-param>
      
          <dependency>
              <groupId>com.sun.faces</groupId>
              <artifactId>jsf-impl</artifactId>
              <version>2.2.11</version>
          </dependency>
      
      <dependency>
          <groupId>org.primefaces</groupId>
          <artifactId>primefaces</artifactId>
          <version>6.0</version>
      </dependency>
      
      <body>
      
      <h:body>
      
      @Inject public VisitorBean() {}
      
      <context-param>
          <param-name>contextClass</param-name>
          <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
      </context-param>