Пользовательский конвертер jsf не работает с областью просмотра

Вот мой код

Пожо

public class Deal implements Serializable {

private int id;
private String name;
private String description;
private Customer customer;
    //getter setter omitted
}

public class Customer implements Serializable {

private int id;
private String name;
private String email;
private String phone;
    //getter setter and equal hashcode omitted
}

Управляемый компонент

@ManagedBean(name="dealBean")
@ViewScoped
public class DealBean implements Serializable {

private List<Customer> customerList;
private List<Deal> dealList;
private Deal deal;

    @PostConstruct
    public void init() {
    deal = new Deal();
    dealList = new ArrayList<Deal>();
    customerList = new ArrayList<Customer>();
    customerList.add(new Customer(1, "MPRL", "[email protected]", "1234455"));
    customerList.add(new Customer(2, "Total", "[email protected]", "3434323"));
    customerList.add(new Customer(3, "Petronas", "[email protected]", "8989876"));

}
    //getter setter omitted

}

Конвертер клиентов

@FacesConverter("customerConverter")
public class CustomerConverter implements Converter {

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String customerID) {
    DealBean dealBean = (DealBean)  FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("dealBean");
    if (dealBean != null) {
        List<Customer> customerList = dealBean.getCustomerList();
        for (Customer customer : customerList) {
            if (customerID.equals(String.valueOf(customer.getId()))) {
                return customer;
            }
        }
    }
    return null;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) {
    if (obj != null) {
        return String.valueOf(((Customer)obj).getId());
    }
    return null;
}

}

XHTML

Customer : <h:selectOneMenu id="customer" value="#{dealBean.deal.customer}">
        <f:converter converterId="customerConverter" />
        <f:selectItems value="#{dealBean.customerList}" var="cus"
            itemLabel="#{cus.name}" itemValue="#{cus}" />
    </h:selectOneMenu>

Когда управляемый компонент находится в области запроса или сеанса, pojo Customer правильно устанавливается в pojo Deal. Проблема заключается в том, что когда управляемый компонент находится в области просмотра, для pojo Customer установлено значение Deal pojo как NULL.

Я использую JSF 2.2.0

Большое спасибо за помощь заранее.


person user3655705    schedule 20.05.2014    source источник
comment
Вам следует использовать инжекторы CDI, если вы используете EE 6 или 7, а не JSF, какую версию вы используете, зачем использовать «@ManagedBean»   -  person rekiem87    schedule 20.05.2014
comment
@ rekiem87 Я использую Tomcat для запуска приложения JSF.   -  person user3655705    schedule 20.05.2014


Ответы (1)


Это не преобразователь, это представление с ограниченной областью действия сломано: поскольку вы используете теги JSF, вы не можете использовать аннотацию @ViewScoped, потому что она была удалена из спецификации и восстановлена ​​​​только для использования CDI. Вы можете использовать представление omnifaces с областью видимости или компоненты apache myFaces (лично я рекомендую omnifaces). Вы можете подтвердить это, создав

System.out.print("Creating");

в конструкторе и проверяя, как вызывается каждый запрос Ajax, поэтому bean-компонент не восстанавливается, и, поскольку он помечен как представление и является частичным запросом, значения не устанавливаются снова (если вы не отправляете всю форму, что не является хорошим решением ), другим обходным путем может быть выполнение запроса bean-компонента и восстановление всех данных при каждом запросе, создание сеанса (но он будет активен для сеанса) или @ConvesationScoped, в котором вам придется уничтожить и начать диалог вручную. Опять же, моей первой рекомендацией может быть переход на сервер, совместимый с Java ee, и использование аннотаций CDI, поскольку JSF устаревает и больше не обновляется.

person rekiem87    schedule 20.05.2014
comment
Спасибо за ответ. Но почему я не могу использовать теги JSF с @ViewScoped? Эта область видимости добавлена ​​в JSF2, не так ли? Конечно, я посмотрю на омнифейсы. - person user3655705; 20.05.2014
comment
Да, но был восстановлен как аннотация CDI, вы можете посмотреть, javax.faces.view.ViewScoped - это рабочий (CDI), а javax.faces.bean.ViewScoped (JSF) в новых реализациях сломан, они даже были помещены в другой пакет с намерением удалить второй в ближайшем будущем все это потому, что спецификация Java EE расширилась и теперь охватывает весь жизненный цикл JSF, поэтому сейчас это считается ненужным - person rekiem87; 20.05.2014