После переключения @ManagedBean на @Named: javax.el.PropertyNotFoundException: Target Unreachable, идентификатор «человек» разрешен до нуля

Я просто тестирую эту страницу JSF, поэтому я не устанавливаю атрибут action в файле <h:commandButton/>. Это очень простая форма с тремя полями для ввода имени, фамилии и электронной почты и одной кнопкой «Сохранить». Каждый раз, когда я нажимаю эту кнопку, я получаю эту ошибку

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

но если я аннотирую свой JavaBean @ManagedBean, то форма проходит нормально, но каждый раз, когда я переключаюсь обратно на использование @Named Bean, я снова получаю эту ошибку. Я попробовал некоторые из предложений, которые я нашел на этом сайте, такие как перезапуск сервера, проверка наличия геттеров, но это не помогло.

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

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>

person Meme Composer    schedule 16.04.2015    source источник
comment
Да, забыл упомянуть, это GlassFish 4.1.   -  person Meme Composer    schedule 16.04.2015
comment
Должен действительно просто работать с коробкой в ​​​​контейнере Java EE 7. У вас есть /WEB-INF/beans.xml?   -  person BalusC    schedule 16.04.2015
comment
Нет, не знаю. Вот и я тоже подумал   -  person Meme Composer    schedule 16.04.2015
comment
RequestScoped должно быть javax.enterprise.context.RequestScoped вместо CDI. Не смешивайте объем JSF и объем CDI.   -  person Charlee Chitsuk    schedule 16.04.2015
comment
@Charlee Это правильно (я уже хотел отметить это в своем ответе, если таковой имеется), но это не причина этой проблемы. Компонент CDI без области действия по умолчанию на странице JSF уже запрашивает область действия.   -  person BalusC    schedule 16.04.2015
comment
@BalusC Я полностью с тобой согласен.   -  person Charlee Chitsuk    schedule 16.04.2015
comment
@BalusC, зачем мне нужен файл beans.xml, чтобы заставить CDI Bean работать?   -  person Meme Composer    schedule 16.04.2015
comment
Вероятно, это еще одна ошибка GF4. Пробовали ли вы удалить все файлы конфигурации web.xml, faces-config.xml и beans.xml, чтобы использовались голые значения по умолчанию?   -  person BalusC    schedule 17.04.2015
comment
@BalusC Нет, я пытался создать файл faces-config.xml, но это не решило проблему, пока я не добавил beans.xml, но если я удалил beans.xml, я получил эту ошибку   -  person Meme Composer    schedule 17.04.2015
comment
У вас есть файлы JAR в /WEB-INF/lib?   -  person BalusC    schedule 17.04.2015
comment
@BalusC У меня даже нет этой папки lib, я просто добавил JSF-файл jar, щелкнув правой кнопкой мыши раздел Libraries в Netbeans, но это не имело никакого значения, поскольку у GlassFish тоже есть этот jar-файл.   -  person Meme Composer    schedule 17.04.2015
comment
У вас действительно не должно быть никаких.   -  person BalusC    schedule 17.04.2015
comment
Я использовал GlassFish Server 4.0 в течение длительного времени, пока несколько месяцев назад не обновил GlassFish до 4.1, и с тех пор я использую GlassFish Server 4.1. Ни в 4.0, ни в 4.1 явно не требовалось beans.xml. (Приложение уже прошло через все версии Mojarra 2.2.x попеременно - начиная с Mojarra 2.2.0 до 2.3.0-m01).   -  person Tiny    schedule 17.04.2015
comment
@BalusC @Tiny Я не знаю, что происходит с моим GS, стандартное расположение ресурсов у меня тоже не работает. Я тестирую фиктивный файл сценария, помещаю его в подпапку scripts в папке resources, а папка resources находится в папке META-INF, а затем в корне приложения, используя <h:outputScript />, но я продолжаю получать Unable to find resource . Моя структура такова, JavaServerFaces - это родительский каталог, в котором расположены все остальные папки, затем в нем есть папка resources, внутри папки resources находится подпапка scripts, где хранится файл скрипта   -  person Meme Composer    schedule 17.04.2015
comment
Вставьте папку resources прямо в корень веб-приложения. (META-INF предназначен для автономного модуля в отдельно упакованном файле JAR, который в конечном итоге заканчивается /WEB-INF/lib в связанном файле WAR).   -  person Tiny    schedule 18.04.2015
comment
@Tiny Да, я тоже это сделал, у меня есть папка resources в родительской папке JavaServerFaces, а папка resources затем подразделяется на более мелкие папки для лучшей организации ресурсов, в этом случае я ненавижу подпапку scripts, которая содержит фиктивный файл javascript. Ох, так расстраивает, я не знаю, что не так с моим GS   -  person Meme Composer    schedule 18.04.2015
comment
Вы можете просмотреть этот ответ на случай, если вы случайно что-то упустили. Возможно, что-то в строке <h:outputScript library="..." name="..." /> идет не так. И, пожалуйста, не забудьте жестко развернуть приложение хотя бы один раз после внесения этих изменений. Если проблема все еще сохраняется, вы можете задать отдельный вопрос.   -  person Tiny    schedule 18.04.2015


Ответы (3)


Вам нужно изменить аннотацию области запроса с лиц на CDI.

Причина в том, что если вы посмотрите на свои аннотации

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

@Named
@RequestScoped

Ни один из них не является CDI "аннотациями, определяющими bean-компоненты", поэтому, если вы используете bean-discovery-mode="annotated", это не сработает для вас.

person John Ament    schedule 16.04.2015
comment
и почему за это проголосовали? - person John Ament; 16.04.2015
comment
Потому что это ничего не объясняло. Объясните, как ловить рыбу, а не только давать рыбу. - person BalusC; 16.04.2015
comment
Я знаю, что вопрос старый, но... В вашем beans.xml измените annotated на all. Это должно решить проблему, по крайней мере, это было с моей ошибкой. - person developer10; 05.10.2016

Основная проблема заключается в том, что вы используете аннотации JSF вместо аннотаций CDI. Чтобы это исправить, измените импорт:

import javax.faces.bean.RequestScoped;

to

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>

Наличие файла beans.xml сигнализирует контейнеру сервлетов о том, что приложение использует JSR-299 (Contexts and Dependency Injection) — без него классы приложения также не будут сканироваться на наличие аннотаций CDI и не будет выполняться внедрение зависимостей. Если вы не используете CDI (например, вы используете только простые управляемые компоненты JSF), вам не нужен файл beans.xml.

См. также:

person unwichtich    schedule 16.04.2015
comment
Эм-м-м! Java EE 7 (GlassFish 4.1). beans.xml не требуется, если это явно не требуется. - person Tiny; 16.04.2015
comment
Эй, это работает. Почему это? Разве в спецификациях Java EE не указано, что файлы конфигурации являются необязательными? - person Meme Composer; 16.04.2015
comment
Извините, я думаю, что это скорее хак, а постоянное решение. - person Meme Composer; 19.04.2015

Это лучший ответ на мою проблему ССЫЛКА . Кроме того, файл jar cdi-1.2 по какой-то причине недоступен в GS 4.1, поэтому пакет javax.enterprise.* не присутствовал в моем Netbeans, мне пришлось вручную загрузить этот файл из http://cdi-spec.org/. Теперь все работает нормально, включая DI. И мне не нужно было создавать какие-либо файлы конфигурации, чтобы заставить его работать.

person Meme Composer    schedule 18.04.2015
comment
Очевидно, что он доступен в GlassFish 4.1, который уже является контейнером, совместимым с Java EE, но эти классы упакованы в библиотеку с именем Java EE 7 API Library, содержащую один большой файл JAR с именем javaee-api-7.0.jar. Вы можете добавить эту библиотеку в путь к классам вашего веб-модуля во время компиляции по мере необходимости. Нет необходимости добавлять библиотеку CDI отдельно по мере необходимости в базовые контейнеры сервлетов, такие как Apache Tomcat, Eclipse Jetty. - person Tiny; 19.04.2015
comment
Причина, по которой jar CDI 1.2 недоступен в GlassFish 4.1, заключается в том, что он упаковывает CDI 1.1. - person John Ament; 19.04.2015