Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
JavaServer Faces portlet does not do command action
I put together a simple java serverfaces application using the Maven
archetype to build it. It is based upon a texbook example from Cay
Horstmann's _Core Java Server Faces_ book. The issue that when you
answer question 1 on the first page, it navigates to
"/success.xhtml" based upon the rule in
faces-config.xml. It does correctly, so I believe. The issue
comes when I am on /success.xhtml and it asks me the next
question. I hit the commandButton that calls the action
quizBean.answerAction. When I look at the debug output, I
don't see any evidence of this action being called! It's as if bridge
lost track of itsself and bounces back to /view.xhtml. I am
not sure why this happens. Any tips?
<?xml version="1.0"?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
>
<lifecycle>
<phase-listener>com.liferay.faces.util.lifecycle.DebugPhaseListener</phase-listener>
<phase-listener>com.liferay.faces.util.lifecycle.ViewScopePhaseListener</phase-listener>
</lifecycle>
<navigation-rule>
<from-view-id>/done.xhtml</from-view-id>
<navigation-case>
<from-outcome>startOver</from-outcome>
<to-view-id>/view.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/again.xhtml</from-view-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/failure.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/success.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/success.xhtml</from-view-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/again.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/success.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/view.xhtml</from-view-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/again.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/success.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<resource-bundle>
<base-name>com.corejsf.messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>
</faces-config>
/success.xhtml
<?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">
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<h:head>
<h:outputStylesheet library="css" name="main.css" />
</h:head>
<h:body>
<h:panelGroup id="panelId" layout="block">
<h:form>
<p>
#{msgs.correct}
<h:outputFormat value="#{msgs.score}">
<f:param value="#{quizBean.score}"/>
</h:outputFormat>
</p>
<p>#{msgs.nextProblem}</p>
<p>#{quizBean.question}</p>
<p><h:inputText value="#{quizBean.response}"/></p>
<p>
<h:commandButton value="#{msgs.checkAnswer}" action="#{quizBean.answerAction}">
</h:commandButton>
</p>
</h:form>
</h:panelGroup>
</h:body>
</f:view>
Quiz bean
package com.corejsf;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.portlet.PortletRequest;
import javax.portlet.annotations.PortletSessionScoped;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.WebKeys;
@Named // or @ManagedBean
@PortletSessionScoped
public class QuizBean implements Serializable {
private static final long serialVersionUID = -4712268339879239065L;
private int currentProblem;
private int tries;
private int score;
private String response = "";
private String correctAnswer;
private Greeting greeting = new Greeting();
public Greeting getGreeting() {
_log.debug("REturning greeting for bean");
return greeting;
}
@PostConstruct
public void postConstruct() {
_log.info("post construct");
}
// Here, we hardwire the problems. In a real application,
// they would come from a database
private ArrayList<Problem> problems = new ArrayList<Problem>(Arrays.asList(
new Problem(
"What trademarked slogan describes Java development? Write once, ...",
"run anywhere"),
new Problem(
"What are the first 4 bytes of every class file (in hexadecimal)?",
"CAFEBABE"),
new Problem(
"What does this statement print? System.out.println(1+\"2\");",
"12"),
new Problem(
"Which Java keyword is used to define a subclass?",
"extends"),
new Problem(
"What was the original name of the Java programming language?",
"Oak"),
new Problem(
"Which java.util class describes a point in time?",
"Date")));
public String getQuestion() {
_log.info("Question number is " + currentProblem);
_log.info("Calling get question " + problems.get(currentProblem).getQuestion());
return problems.get(currentProblem).getQuestion();
}
public String getAnswer() {
_log.info("get correct answer is " + correctAnswer);
return correctAnswer;
}
public int getScore() {
return score;
}
public String getResponse() {
return response;
}
public void setResponse(String newValue) {
response = newValue;
}
public String answerAction() {
_log.info("answer Action called");
tries++;
_log.info("answerAction. tries is " + tries);
if (problems.get(currentProblem).isCorrect(response)) {
score++;
nextProblem();
if (currentProblem == problems.size())
return "done";
else
return "success";
}
else if (tries == 1)
return "again";
else {
nextProblem();
if (currentProblem == problems.size())
return "done";
else
return "failure";
}
}
public String startOverAction() {
Collections.shuffle(problems);
currentProblem = 0;
score = 0;
tries = 0;
response = "";
return "startOver";
}
private void nextProblem() {
_log.info("CAlling next problem");
correctAnswer = problems.get(currentProblem).getAnswer();
currentProblem++;
tries = 0;
response = "";
}
@Inject
private PortletRequest portletRequest;
public String getName() {
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
User user = themeDisplay.getUser();
return user.getFirstName() + " " + user.getLastName();
}
// Logger
private static final Log _log = LogFactoryUtil.getLog(QuizBean.class);
}
Powered by Liferay™