Как сформировать @Named Backing Bean в JSF

Я где-то читал, что лучше использовать CDI @Named вместо JSF @ManagedBean из-за CDI, поэтому я пытаюсь преобразовать часть своего кода. Я пытаюсь использовать @Named в JSF, но он всегда недоступен. При использовании @ManagedBean проблем не было.

Я использую его как @ManagedBean, как показано ниже

CustomerBacking.java

package com.wordpress.marczykm.backing;

import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("customer")
@RequestScoped
public class CustomerBacking {

    @EJB
    private CustomerService customerService;

    public CustomerBacking() {
    }

    public String addCustomer(Customer customer) {
        customerService.addCustomer(customer);
        return "customer_overview";
    }

    public Customer getCustomer(){
        return customerService.getCustomer();
    }
}

index.xhtml

    <!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:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>EJB 3.0 Test</title>
    </h:head>
    <h:body>
        <h:outputText value="#{customer.firstname}"/>
        <h:form>
            <h:outputText value="Imię"/>
            <h:inputText id="firstname" name="firstname" value="#{customer.firstname}" /><br/>

            <h:outputText value="Nazwisko"/>
            <h:inputText id="lastname" name="lastname" value="#{customer.lastname}" /><br/>

            <h:commandButton value="Dodaj" actionListener="#{customer.addCustomer}"/>
        </h:form>
</h:body>
</html>

person Marcin Marczyk    schedule 12.02.2014    source источник
comment
Вы смешали пространства имен JSF и пространства имен CDI. Вместо этого попробуйте import javax.enterprise.context.RequestScoped. Также ваш код резервного компонента и xhtml не совпадают, но я предполагаю, что это ошибка копирования и вставки.   -  person mabi    schedule 12.02.2014
comment
хорошо, я отредактировал код (изменил на правильный оператор импорта и изменил аннотацию на @Named("customer")), но все же после нажатия CommandButton у меня есть ошибка Target Unreachable, идентификатор 'customer' преобразован в null   -  person Marcin Marczyk    schedule 12.02.2014
comment
Как именно вы установили/включили CDI в своей среде? По умолчанию он отключен, а на некоторых серверах (например, Tomcat) даже по умолчанию не установлен.   -  person BalusC    schedule 12.02.2014
comment
я только что создал новый Динамический веб-проект с помощью Spring Tool Suite и отметил Java Server Faces в проекте Properties/Project Facets   -  person Marcin Marczyk    schedule 12.02.2014
comment
Я не просил об этом. Могу ли я предположить, что вы понятия не имеете, как и когда CDI включается для среды? С технической точки зрения, у вас вообще нет файла /WEB-INF/beans.xml в папке веб-контента?   -  person BalusC    schedule 12.02.2014
comment
это все шаги, которые сделал. я добавил beans.xml, где вы сказали. я должен объявить там BackingBeans или он может иметь только <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>   -  person Marcin Marczyk    schedule 12.02.2014
comment
Хорошо, тогда среда (сервер, на котором вы развертываете веб-приложение), по-видимому, изначально не поддерживает CDI. Какой это сервер? Кот? Как именно вы тогда установили CDI? Кстати, вы не объявляете поддержку bean-компонентов. Вместо этого вы объявляете управляемые компоненты. С помощью @Named вы объявляете класс вспомогательного компонента как управляемый компонент CDI. С помощью @ManagedBean вы объявляете класс вспомогательного компонента как управляемый компонент JSF. Вы понимаете суть?   -  person BalusC    schedule 12.02.2014
comment
Ладно, я понял. Я использую Glassfish, поддерживает ли он CDI изначально?   -  person Marcin Marczyk    schedule 12.02.2014
comment
Перейдите к этому ответу stackoverflow.com/a/12012663/221951 и посмотрите, полезен ли он для вас. Кажется, вы перепутали некоторые понятия.   -  person Piotr Gwiazda    schedule 13.02.2014


Ответы (2)


Подводя итог, глядя на пример приложения CDI Netbeans, bean-компонент, который должен быть доступен на странице JSF, должен:

  • иметь аннотацию @Named (javax.inject.Named)
  • иметь аннотацию области действия (например, @SessionScoped, @RequestScoped, @ViewScoped), но импортированную из javax.enterprise.context.*
  • не обязательно иметь пустой конструктор без аргументов
  • и то, чего не было в моем коде, это то, что bean-компонент должен реализовать Serializable (java.io.Serializable)
  • последнее, что если ваше приложение является веб-приложением, ему нужен beans.xml (может быть полностью пустым) в каталоге WEB-INF, если это приложение bean, оно должно находиться в каталоге META-INF
person Marcin Marczyk    schedule 20.02.2014

Вы не указываете, какой контейнер сервлетов/сервер приложений и какую версию реализации CDI вы используете.

Я понятия не имею, что Spring Tool Suite принимает по умолчанию, предположительно, это Tomcat, Spring и вообще никакого CDI, поэтому вам нужно добавить и настроить реализацию CDI (например, Weld или OpenWebBeans).

Для CDI 1.0 вам нужно будет добавить дескриптор WEB-INF/beans.xml (который может быть пустым), чтобы ваши bean-компоненты были обнаружены. Это больше не требуется для CDI 1.1.

person Harald Wellmann    schedule 12.02.2014