2011-10-17 13 views
20

Tengo una página de facelets JSF que muestra una tabla de datos según la página que están viendo. Cuando visualizo la página 1, llamo al método de acción view() para obtener los datos de la base de datos para ambas páginas y almacenarlos como un campo de miembro privado del bean (dos matrices). También llamo al conversation.start() en la instancia de conversación inyectada en el método view().¿Cómo funciona JSF 2 ConversationScope?

Cuando el usuario hace clic en el botón "siguiente" (h:commandButton) para ir a la página 2, Estoy ejecutando un método next() para actualizar el bean de respaldo para que apunte a la matriz 2 por lo que se imprimirá su contenido. El problema es que la matriz 2 ya no existe. No sé por qué estoy perdiendo alcance de conversación. ¿Algunas ideas?

//tells the object which page we are on, and thus what data to display. 
private int part = 1; 

// These arrays are filled with data but conversation scope doesn't 
// keep them on the next postback. 
private int[] part1 = new int[15], part2 = new int[15]; 

Respuesta

42

Debe pegar más código para que podamos ayudarlo mejor. Por lo que dices, no puedo ver dónde llamaste el método para finalizar la conversación (lo necesitas también cuando trabajas con el alcance de la conversación).

voy a pegar aquí un pequeño ejemplo que creo que le ayudará a entender cómo funciona ámbito de conversación:

Esta es la página de inicio de un asistente (ámbito de conversación es ideal para magos)

<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>ConversationScoped demo CDI(Component Dependency 
    Injection)</title> 
</h:head> 

<h:body> 



    <h3>ConversationScoped demo CDI(Component Dependency Injection)</h3> 

    <p>A conversation scope provides persistence until a goal is 
    reached<br /> 
    In this example the first entered value will remain until the end 
    method is called<br /> 
    in some page.<br /> 
    This is a really useful gadget, for making registration wizards and 
    similar tools...</p> 

    <h:form> 
     <h:outputText value="Type something" /> 
     <h:inputText value="#{ supportBB.someValue}" /> 
     <h:commandButton value="continue" action="#{ supportBB.onClick}" /> 
    </h:form> 

</h:body> 
</html> 

Esta es la segunda página del asistente

<!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>ConversationScoped demo CDI(Component Dependency 
    Injection)</title> 
</h:head> 

<h:body> 



    <h3>This is the next page(The value is saved in the conversation)</h3> 

     <h4><h:outputText value="#{ supportBB.someValue}"/></h4> 

    <h:form>   
     <h:commandButton value="Finish conversation" action="#{ supportBB.onKeepGoing}"/> 
    </h:form> 

</h:body> 
</html> 

Y esta es la página donde termina el alcance

<!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>ConversationScoped demo CDI(Component Dependency 
    Injection)</title> 
</h:head> 

<h:body> 



    <h3>This is the last page.The value still saved in conversation(until the end() method is called)</h3> 

    <h4><h:outputText value="#{ supportBB.someValue}" /></h4> 

    <h:form> 
     <h:outputText 
      value="Click finish to end the conversation(So saved values are disposed)" /> 
     <h:commandButton value="Finish" action="#{ supportBB.onFinish}" /> 
    </h:form> 

</h:body> 
</html> 

Aquí el bean de respaldo @ConversationScoped que empieza y termina la conversación

package backingbeans; 

import java.io.Serializable; 

import javax.enterprise.context.Conversation; 
import javax.enterprise.context.ConversationScoped; 
import javax.inject.Inject; 
import javax.inject.Named; 

@Named() 
@ConversationScoped() 
public class SupportBB implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String someValue; 
    @Inject 
    private Conversation conversation; 

    // Control start and end of conversation 
    public void start() { 
     conversation.begin(); 
    } 

    public void end() { 
     conversation.end(); 
    } 

    // Navigation 
    public String onClick() { 
     if(someValue.equals("") || conversation == null) { 
      return "";//Dont go anywhere if the there was no input the field 
     } 
     start(); 
     return "nextpage?faces-redirect=true"; 
    } 

public String onKeepGoing() { 
    return "finish?faces-redirect=true"; 
} 

public String onFinish() { 
    end();// If triggered when there is no conversation(i.e URL Navigation) 
      // there will be an exception 
    return "index?faces-redirect=true"; 
} 

// Getters & Setters 
public String getSomeValue() { 
    return someValue; 
} 

public void setSomeValue(String someValue) { 
    this.someValue = someValue; 
} 

} 

creo que este ejemplo es muy simple y puede ayudarlo a entender cómo funciona. Preguntar si no entiende algo

NOTA:

creo, pero no estoy seguro al 100%, pero ConversationScope sólo funciona si el bean de respaldo es un grano de CDI. Esta media usa la anotación @Named. Mejor revise eso.

+0

Gracias por la respuesta. Tendré que intentarlo cuando regrese a mi otra computadora esta noche. ¿Necesito los redireccionamientos o puedo pasar la página? – Adam

+3

@ Adam Fisher Puede pasar la página pero siempre me gusta usar los redireccionamientos, solo para asegurarse :) – sfrj

+4

Gracias por el ejemplo detallado. Mi problema fue usar @ManagedBean en lugar de @Named() con el alcance. – Adam

Cuestiones relacionadas