I have a problem with the propagation of a long running conversation when I redirect the view by the handleNavigation()
method. Here is my test code:
I have a conversationscoped
bean and two views:
conversationStart.xhtml
is called in Browser with URL
http://localhost/tests/conversationStart.jsf?paramTestId=ParameterInUrl
<!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:f="http://java.sun.com/jsf/core">
<f:metadata>
<f:viewParam name="paramTestId" value="#{conversationTest.fieldTestId}" />
<f:event type="preRenderView" listener="#{conversationTest.preRenderView}" />
</f:metadata>
<h:head>
<title>Conversation Test</title>
</h:head>
<h:body>
<h:form>
<h2>Startpage Test Conversation with Redirect</h2>
<h:messages />
<h:outputText value="Testparameter: #{conversationTest.fieldTestId}"/><br />
<h:outputText value="Logged In: #{conversationTest.loggedIn}"/><br />
<h:outputText value="Conversation ID: #{conversationTest.convID}"/><br />
<h:outputText value="Conversation Transient: #{conversationTest.convTransient}"/><br />
<h:commandButton action="#{conversationTest.startLogin}" value="Login ->" rendered="#{conversationTest.loggedIn==false}" /><br />
<h:commandLink action="/tests/conversationLogin.xhtml?faces-redirect=true" value="Login ->" rendered="#{conversationTest.loggedIn==false}" /><br />
</h:form>
<h:link outcome="/tests/conversationLogin.xhtml" value="Login Link" rendered="#{conversationTest.loggedIn==false}">
<f:param name="cid" value="#{conversationTest.convID}"></f:param>
</h:link>
</h:body>
</html>
The Parameter is written to the beanfield
and displayed in the view correctly. There are 3 different possibilities to navigate to the next View. All 3 work fine. The beanfield
shows up the next view (conversationLogin.xhtml
) too:
<!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:f="http://java.sun.com/jsf/core">
<h:head>
<title>Conversation Test</title>
</h:head>
<h:body>
<h:form>
<h2>Loginpage Test Conversation with Redirect</h2>
<h:messages />
<h:outputText value="Testparameter: #{conversationTest.fieldTestId}"/><br />
<h:outputText value="Logged In: #{conversationTest.loggedIn}"/><br />
<h:outputText value="Conversation ID: #{conversationTest.convID}"/><br />
<h:outputText value="Conversation Transient: #{conversationTest.convTransient}"/><br />
<h:commandButton action="#{conversationTest.login}" value="Login And Return" /><br />
</h:form>
</h:body>
</html>
When I return to the Startpage by clicking the button the conversation bean still contains all values. So everything is fine. Here is the bean:
package test;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@ConversationScoped
public class ConversationTest implements Serializable{
private static final long serialVersionUID = 1L;
final String CONVERSATION_NAME="longRun";
@Inject Conversation conversation;
private boolean loggedIn;
private String fieldTestId;
@PostConstruct
public void init(){
if(conversation.isTransient()){
conversation.begin(CONVERSATION_NAME);
System.out.println("New Conversation started");
}
loggedIn=false;
}
public String getConvID(){
return conversation.getId();
}
public boolean isConvTransient(){
return conversation.isTransient();
}
public boolean getLoggedIn(){
return loggedIn;
}
public String startLogin(){
return "/tests/conversationLogin.xhtml?faces-redirect=true";
}
public String login(){
loggedIn=true;
return "/tests/conversationStart.xhtml?faces-redirect=true";
}
public void preRenderView(ComponentSystemEvent ev) {
// if(!loggedIn){
// System.out.println("Will redirect to Login");
// FacesContext ctx = FacesContext.getCurrentInstance();
// ctx.getApplication().getNavigationHandler().handleNavigation(ctx, null, "/tests/conversationLogin.xhtml?faces-redirect=true");
// ctx.renderResponse();
// }
}
public void setFieldTestId(String fieldTestId) {
System.out.println("fieldTestID was set to: "+fieldTestId);
this.fieldTestId = fieldTestId;
}
public String getFieldTestId() {
return fieldTestId;
}
}
Now comes the problem
As soon as I try to redirect the page in the preRenderView
method of the bean (just uncomment the code in the method), using handleNavigation()
the bean is created again in the next view instead of using the already created instance. Although the cid
parameter is propagated to the next view !
Has anybody an idea what's wrong ?
best regards Thomas