将 @ManagedBean 切换为 @Named 后:javax.el.PropertyNotFoundException:目标无法访问,标识符 'person' 解析为空

After switching @ManagedBean to @Named: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'person' resolved to null

我只是测试这个 JSF 页面,所以我没有在 <h:commandButton/> 中设置 action 属性。这是一个非常简单的表单,有 3 个输入框(名字、姓氏和电子邮件)和一个名为“保存”的按钮。每次单击该按钮时,我都会收到此错误

javax.el.PropertyNotFoundException: /index.xhtml @19,106 value="#{person.firstName}": Target Unreachable, identifier 'person' resolved to null

但是如果我注释我的 JavaBean @ManagedBean,那么表单就可以正常运行,但是每次我切换回使用 @Named Bean 时,我都会再次收到该错误。我已经尝试了我在该站点上找到的一些建议,例如重新启动服务器、检查 getter 是否存在,但这些都没有帮助。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <meta charset="UTF-8" />
        <title>Simple Form Created Using Facelets</title>
    </h:head>

    <h:body>
        <h:messages/>
        <h:form>
            <h:panelGrid columns="2" columnClasses="rightColumn, leftColumn">

                <h:outputLabel for="firstName" value="First Name:" />
                <h:inputText id="firstName" value="#{person.firstName}"
                             label="First Name"/>

                <h:outputLabel for="lastName" value="Last Name:" />
                <h:inputText id="lastName" value="#{person.lastName}" label="Last Name"/>

                <h:outputLabel for="email" value="Email:"/>
                <h:inputText id="email" value="#{person.email}" label="Email" />

                <h:panelGroup />
                <h:commandButton value="Submit"/>
            </h:panelGrid>
        </h:form>
    </h:body>
</html>

这是我的 JavaBean class

import javax.annotation.PostConstruct;
import javax.faces.bean.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class Person {

    private String firstName = "empty";
    private String lastName = "empty";
    private String email = "empty";

    public void Person() {}

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

这是 web.xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 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_3_1.xsd">

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

主要问题是您使用的是 JSF 注释而不是 CDI 注释。要解决此问题,请更改导入:

import javax.faces.bean.RequestScoped;

import javax.enterprise.context.RequestScoped;

但是,另一种解决方案是创建一个 beans.xml 文件。

为此,请在 WEB-INF 文件夹中创建一个,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_0.xsd">
</beans>

The presence of a beans.xml file signals the servlet container that the application uses JSR-299 (Contexts and Dependency Injection) - without it, the application's classes will not be scanned for CDI annotations either and dependency injection will not be performed. If you don't use CDI (e.g. you only use plain JSF managed beans), you don't need beans.xml.

另请参阅:

  • Why are there different bean management annotations

您需要将请求范围内的注释从人脸更改为 CDI。

原因是如果你看看你的注释

import javax.annotation.PostConstruct;
import javax.faces.bean.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped

None 其中是 CDI "bean defining annotations",因此如果您使用 bean-discovery-mode="annotated" 它不会为您工作。

这是我的问题的最佳答案LINK .此外,出于某种原因,cdi-1.2 jar 文件在 GS 4.1 中不可用,这就是为什么包 javax.enterprise.* 不存在于我的 Netbeans 中,我不得不从 http://cdi-spec.org/ 手动下载该 jar。现在一切正常,包括 DI。而且我也不需要创建任何配置文件来让它工作。