¿Por qué @PostConstruct devolución de llamada de fuego cada vez que a pesar de frijol se @ViewScoped? JSF

StackOverflow https://stackoverflow.com/questions/2797231

Pregunta

Estoy utilizando la tabla de datos en la página y el uso de atributo vinculante para obligar a éste a mi bean de respaldo. Este es mi código: -

<?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:p="http://primefaces.prime.com.tr/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
            <h:form prependId="false">

                <h:dataTable var="item" value="#{testBean.stringCollection}" binding="#{testBean.dataTable}">
                    <h:column>
                        <h:outputText value="#{item}"/>
                    </h:column>
                    <h:column>
                        <h:commandButton value="Click" actionListener="#{testBean.action}"/>
                    </h:column>
                </h:dataTable>

            </h:form>

    </h:body>
</html>

Este es mi café en grano: -

package managedBeans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.html.HtmlDataTable;

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

    private List<String> stringCollection;

    public List<String> getStringCollection() {
        return stringCollection;
    }

    public void setStringCollection(List<String> stringCollection) {
        this.stringCollection = stringCollection;
    }

    private HtmlDataTable dataTable;

    public HtmlDataTable getDataTable() {
        return dataTable;
    }

    public void setDataTable(HtmlDataTable dataTable) {
        this.dataTable = dataTable;
    }

    @PostConstruct
    public void init(){
        System.out.println("Post Construct fired!!");
        stringCollection = new ArrayList<String>();
        stringCollection.add("a");
        stringCollection.add("b");
        stringCollection.add("c");

    }

    public void action(){
        System.out.println("Clicked!!");

    }
}

Por favor, dime ¿por qué el @PostConstruct disparando cada vez que haga clic en el botón? Se debe disparar una sola vez, siempre y cuando estoy en mi misma página pd frijol se @ViewScoped. Además, si quito el atributo vinculante entonces todo funciona bien y de devolución de llamada @PostConstruct incendios sólo una vez. Entonces ¿por qué cada vez que cuando uso atributo vinculante? Necesito atributo obligatorio y desea llevar a cabo tareas de inicialización como búsqueda de datos del servicio web, etc sólo una vez. ¿Qué tengo que hacer? ¿Dónde debo escribir mi tarea de inicialización?

¿Fue útil?

Solución

Interesante, frijol cuando se está utilizando la unión en una vista de componentes cuyo ámbito, se rompe la vista alcance.

No estoy seguro de si eso es un error en JSF2, tendría que leer toda la especificación JSF2 primero. En lo que ahora lo mejor es dejar caer el componente de unión por ahora y pasar el elemento seleccionado a través de una nueva sintaxis argumento 2.2 EL método:

<h:dataTable var="item" value="#{testBean.stringCollection}">
    <h:column>
        <h:outputText value="#{item}"/>
    </h:column>
    <h:column>
        <h:commandButton value="Click" action="#{testBean.action(item)}"/>
    </h:column>
</h:dataTable>

Ver también:


Actualizar (diciembre 2012): esto es de hecho un error en JSF2. Es una cuestión de huevo y la gallina. La vista de ámbito de granos se almacenan en el estado de vista JSF. Por lo que la vista de ámbito granos obtiene después de restaurar la fase de vista. Sin embargo, las carreras de atributos binding durante la fase de restauración de la vista, mientras que la vista de ámbito granos aún no están disponibles. Esto hace que la creación de un nuevo punto de vista de ámbito instancia del bean, que luego es reemplazado más tarde por la visión real de ámbito frijol que se almacena en el estado de vista JSF restaurado.

Este es reportado como JSF edición 1492 y JSF spec isssue 787 que se fijará para JSF 2.2. Hasta entonces, la mejor opción es utilizar binding a petición de ámbito exclusivamente judías, o para buscar formas alternativas para el requisito funcional particular.


Actualizar (mar 2015): La solución JSF 2.2 fue portado a Mojarra 2.1.18. Así que si usted todavía está utilizando JSF 2.0 / 2.1, será mejor que la actualización a por lo menos esa versión. Ver también a.o. ¿Cuál es componente de unión en JSF? Cuando se prefiere utilizar? y JSTL en JSF2 Facelets ... tiene sentido?

Otros consejos

Como otro dijo, yo diría que lo mejor que puede hacer es dejar caer componente de unión (no aquí sí es necesario).

Pero me gustaría añadir que se puede lograr lo mismo que usted está tratando de hacer de una manera más orientada a objetos mediante el uso de parámetros de acción, así:

<h:commandButton value="Click" action="#{testBean.action(item)}"/>

... y en el código Java:

  public void action(Item item){
    System.out.println("Clicked!!" + item);
}

Si usted tiene un grano viewscoped y si desea conservar valores introducidos en el formulario o no quieren PostConstruct despedido, debe devolver null de su método de acción.

Si devuelve algún resultado (por ejemplo no válido) y luego apuntar el resultado no válido a la misma página utilizando faces-config.xml, entonces el frijol viewscoped se regenere y por lo tanto hace que PostConstruct al fuego de nuevo.

otra solución:

  • Encuadernación la HtmlDataTable en un grano de solicitud alcance.
  • Inject esta solicitud alcance de frijol en el grano de vista alcance.

JBoss Seam utilizar esta solución para Componentes JSF unirse a un componente ámbito de conversación.

La respuesta de la balusc me ha ayudado mucho, me gustaría decir que tuve ese error con la versión 2.1.7 mojarra, actualmente estoy usando 2.1.29-01 publicado en enero de 2015 y este error se corrige, mi problema se encontraba en vigor una TabView a un bean viewscoped. Con esta versión no tengo ese error y vinculante y PostConstruct está funcionando bien. Puedo utilizar JBoss 5.2 y tengo que usar mojarra 2.1.x así que espero que esta respuesta ayuda a otras personas en la misma situación.

http://mvnrepository.com/artifact/ com.sun.faces / JSF-api / 2.1.29-01 http://mvnrepository.com/artifact/com.sun .faces / JSF-impl / 2.1.29-01

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top