JSF 2: проблема ViewScoped, бин не сохраняется при повторном отображении той же страницы - PullRequest
4 голосов
/ 24 декабря 2010

Я уверен, почему, но мой viewscoped-bean не сохраняется при повторном отображении той же страницы. Мне интересно, если это из-за использования шаблонов Facelet?

Вот что я сделал, чтобы помочь мне решить проблему:

  1. Добавить метод @PostConstruct и отладить оттуда
  2. Добавьте отладку в метод сеттера и метода получения
  3. Кажется, что в отладке ViewScoped много вызовов методов PostConstruct
  4. И да, состояние не сохраняется (отправьте, установите флаг в значение true, но при повторном отображении флага снова возвращается значение false)
  5. Попробуйте изменить область видимости на сеанс, при сообщении об ошибке «org.glassfish.deployment.common.DeploymentException: WELD-000072 Управляемый компонент, объявляющий пассивирующую область, должен быть пассивирован» при перезапуске моей стеклянной рыбы. Пришлось сделать сериализуемым мой бин, чтобы пропустить эту ошибку.
  6. А в bean-объекте сеанса PostConstruct вызывается только один раз, и состояние сохраняется

Интересно, что пошло не так с моим чехлом ViewScope?

Вот мой файл facelet: «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<h:head>
    <title>#{msgs.title}</title>
    <h:outputStylesheet library="css" name="main.css" />
</h:head>
<h:body>
    <ui:composition template="/template/masterlayout.xhtml">
        <ui:define name="windowTitle">Checkbox Lab</ui:define>
        <ui:define name="heading">Checkbox Lab</ui:define>
        <ui:define name="content">
            <h:form>
                <p:messages id="messages" globalOnly="true"/>
                <h:panelGrid columns="3" styleClass="bordered">
                    <h:outputLabel for="Married" value="Married" />
                    <h:selectBooleanCheckbox label="Married" id="Married" 
                         value="#{checkboxLabBean.married}" />
                    <p:message for="Married"/>

                    <p:panel header="debug info" id="debugPanel"
                        toggleable="true" toggleSpeed="300" >
                            <h:panelGrid columns="2">
                            <h:outputText value="rendered :"/> 
                            #{checkboxLabBean.submitted}

                            <h:outputText value="married status :"/> 
                            #{checkboxLabBean.married}
                            </h:panelGrid>
                    </p:panel>
                </h:panelGrid>
                <h:commandButton value="Refresh"
                    action="#{checkboxLabBean.submit}"/>
            </h:form>
        </ui:define>
    </ui:composition>
</h:body>
</html>

А вот мой боб:

package user.ui;

import java.io.Serializable;

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

@Named
@ViewScoped
public class CheckboxLabBean implements Serializable {
    private boolean married = true;
    private boolean submitted;

    @PostConstruct
    public void debugPostConstruct() {
        System.out.println("Post Construct !");
    }

    public boolean isMarried() {
        return married;
    }
    public void setMarried(boolean married) {
        this.married = married;
    }
    public boolean isSubmitted() {
        System.out.println("returning submit : " + this.submitted);
        return submitted;
    }
    public void setSubmitted(boolean submitted) {
        this.submitted = submitted;
    }

    public String submit() {
        System.out.println("setting submit to true");
        this.submitted = true;
        return null;
    }
}

Вот вывод моих журналов видимости и сеанса:

просмотр области действия , впервые открытый после перезапуска веб-приложения:

[# | 2010-12-24T11: 01: 11,307 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 01: 11,310 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 01: 11,310 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | возвращение представить: ложь | #]

[# | 2010-12-24T11: 01: 11,311 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 01: 11,322 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 01: 11,322 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 34; _ThreadName = Thread-1; | сообщение Построить! | #]

просмотр области действия после нажатия на кнопку обновления

[# | 2010-12-24T11: 02: 46,129 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,130 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,131 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,131 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,131 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | установка отправить к истине | #]

[# | 2010-12-24T11: 02: 46,133 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,134 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,134 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | возвращение представить: ложь | #]

[# | 2010-12-24T11: 02: 46,134 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,136 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T11: 02: 46,136 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | сообщение Построить! | #]

объем сеанса , впервые открытый после перезапуска веб-приложения:

[# | 2010-12-24T10: 58: 54,610 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 32; _ThreadName = Thread-1; | сообщение Построить! | #]

[# | 2010-12-24T10: 58: 54,612 + 0700 | INFO | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 32; _ThreadName = Thread-1; | возвращение представить: ложь | #]

объем сеанса после нажатия на кнопку обновления:

[# | 2010-12-24T10: 59: 14.613 + 0700 | INFO | glassfish3.0.1 | org.hibernate.validator.engine.resolver.DefaultTraversableResolver | _ThreadID = 37; _ThreadName = Thread-1; | Создан экземпляр из org.hibernate.validator.engine.resolver.JPATraversableResolver |. #]

[# | 2010-12-24T10: 59: 14,615 + 0700 | ИНФО | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | установка отправить к истине | #]

[# | 2010-12-24T10: 59: 14,617 + 0700 | ИНФО | glassfish3.0.1 | javax.enterprise.system.std.com.sun.enterprise.v3.services.impl | _ThreadID = 37; _ThreadName = Thread-1; | возвращение представить: правда | #]

Ответы [ 3 ]

6 голосов
/ 24 декабря 2010

Кажется, проблема в том, что вы объявляете свой bean-компонент управляемым bean-компонентом CDI , а не управляемым bean-компонентом JSF . @ViewScoped - это специфическая область JSF, которая изначально не поддерживается CDI.

CDI позволяет вам создавать собственные области видимости, поэтому вы можете создать поддержку для него. На самом деле это уже сделано. Смотрите это: http://seamframework.org/Community/JSF2ViewScopeInCDI

Без использования каких-либо расширений следующий код работает отлично:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class MyBean {

    String state = "";

    @PostConstruct
    public void test() {
        System.out.println("pc called");
        state = "state set";
    }

    public String getState() {
        return state;
    }

    public String action() {
        return "";
    }
}

И следующий Facelet:

<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:body>

        #{myBean.state}

        <h:form>
            <h:commandButton value="test" action="#{myBean.action}"/>
        </h:form>
    </h:body>
</html>

Метод пост-конструкции теперь будет вызываться только один раз, и после нажатия кнопки команды страница обновится, но состояние сохранится.

2 голосов
/ 10 сентября 2011

Лицевые поверхности шва 3 предоставляет аннотацию @ViewScoped для компонентов CDI, а также множество других функций для преодоления разрыва между CDI и JSF.

1 голос
/ 28 сентября 2011

Исходя из рекомендаций, размещенных здесь, я начал использовать MyFaces CODI для решения этой проблемы.Я не могу сказать вам, лучше ли Seam или CODI, но, по крайней мере, это позволяет мне двигаться дальше, пытаясь разобраться в прицеле и приступить к кодированию приложения.

...