-->

After switching @ManagedBean to @Named: javax.el.P

2020-04-11 06:21发布

问题:

I am just testing out this JSF page, so I don't set the action attribute in the <h:commandButton/>. This is a very simple form with 3 input boxes for First Name, Last Name, and Email, and one button called Save. Every time I click that button, I receive this error

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

but if I annotate my JavaBean @ManagedBean, then the form go through just fine, but every time I switch back to using @Named Bean, I receive that error again. I have tried some of the suggestions I found on this site such as restarting the server, checking the presence of the getters, but those did not help.

<?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>

This is my 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;
    }
}

This is the web.xml file.

<?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>

回答1:

You need to change your request scoped annotation from faces to CDI.

The reason being is if you look at your annotations

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

@Named
@RequestScoped

None of these are CDI "bean defining annotations" so if you're using bean-discovery-mode="annotated" it's not going to work for you.



回答2:

The main problem is that your using JSF annotations instead of CDI annoations. To fix that, change the import:

import javax.faces.bean.RequestScoped;

to

import javax.enterprise.context.RequestScoped;

However, another solution is to create a beans.xml file.

To do that, create one in the WEB-INF folder with the following content:

<?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.

See also:

  • Why are there different bean management annotations


回答3:

This is the best answer to my problem LINK . Also, cdi-1.2 jar file is not available in GS 4.1 for some reason, that is why the package javax.enterprise.* was not present in my Netbeans, I had to manually download that jar from http://cdi-spec.org/. Now everything works fine including DI. And I did not have to create any configuration files to get it to work either.