将参数从一个 jsf 页面传递到另一个
Pass param from one jsf page to another
我想将 selectedExamId 从 chooseexam 页面传递到考试页面,这样做的好方法是什么?对单个 jsf 页面使用两个 baking bean 是一种好习惯吗?
还有一件事是我每次都得到相同的问题列表?
我有以下 jsf 页面
chooseExam.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">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<h:selectOneRadio value="#{examBean.selectedExamId}">
<f:selectItems value="#{chooseExamBean.exams}" var="exam" itemValue="#{exam.examId}" itemLabel="#{exam.examName}"/>
</h:selectOneRadio>
<h:commandButton value="Submit" action="/user/exam?faces-redirect=true"/>
</ui:define>
</ui:composition>
</h:body>
</html>
和
exam.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">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<ui:repeat value="#{examBean.questions}" var="question">
<h:outputLabel value="#{question.question}"/>
<h:selectOneRadio value="#{examBean.questionAnswerMap[question]}">
<f:selectItem itemValue="#{question.choice1}" itemLabel="#{question.choice1}"/>
<f:selectItem itemValue="#{question.choice2}" itemLabel="#{question.choice2}"/>
<f:selectItem itemValue="#{question.choice3}" itemLabel="#{question.choice3}"/>
<f:selectItem itemValue="#{question.choice4}" itemLabel="#{question.choice4}"/>
</h:selectOneRadio>
</ui:repeat>
<h:commandButton value="Submit" action="#{examBean.calculate}"/>
</ui:define>
</ui:composition>
</h:body>
</html>
以下是支持 bean
ChooseExamBean.java
@Component
@ManagedBean
public class ChooseExamBean {
List<Exam> exams;
@Autowired
private ExamService examService;
@PostConstruct
public void init(){
exams = examService.getAllExams();
}
public List<Exam> getExams() {
return exams;
}
public void setExams(List<Exam> exams) {
this.exams = exams;
}
}
和
ExamBean.java
@Component
@ManagedBean
public class ExamBean {
private List<Question> questions;
private Map<Question, String> questionAnswerMap = new HashMap<>();
private int score;
private Long selectedExamId;
@Autowired
private QuestionService questionService;
@PostConstruct
public void init() {
if(selectedExamId != null)
questions = questionService.getQuestionsForExam(selectedExamId);
}
public Map<Question, String> getQuestionAnswerMap() {
return questionAnswerMap;
}
public void setQuestionAnswerMap(Map<Question, String> questionAnswerMap) {
this.questionAnswerMap = questionAnswerMap;
}
public List<Question> getQuestions() {
if(questions == null)
questions = questionService.getQuestionsForExam(selectedExamId);
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Long getSelectedExamId() {
return selectedExamId;
}
public void setSelectedExamId(Long selectedExamId) {
this.selectedExamId = selectedExamId;
}
public String calculate() {
score = questionAnswerMap.size();
return "result?faces-redirect=true";
}
}
由于您正在为(ExamBean 和 ChooseExamBean)使用 RequestScope Beans,您不能在响应后保留值,因此您应该使用 viewParam 标记将值从第一页传递到第二页。
你应该像下面这样:
1- ChooseExam.jsf ,您有将在 chooseExamBean 中保存其值的单选按钮:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<h:selectOneRadio label="examType" value="#{chooseExamBean.examNumber}">
<f:selectItem itemLabel="exam1" itemValue="1"/>
<f:selectItem itemLabel="exam2" itemValue="2"/>
</h:selectOneRadio>
<h:commandButton value="commandButton1" action="#{chooseExamBean.navigateToExamPage}" />
</h:form>
</h:body>
</html>
</f:view>
2- 在 commandButton 的操作中,您将调用 bean 中的方法进行导航,在导航之前,您将向 url 附加一个参数,例如navigateToExamPage 方法中的以下内容:
@ManagedBean(name = "chooseExamBean")
@RequestScoped
public class ChooseExamBean {
public ChooseExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public Object navigateToExamPage() {
return "exam?faces-redirect=true&examId="+getExamNumber();
}
}
3-在exam.jsf页面中,你必须获取参数的值,在这里你将使用标签,如下所示:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<f:metadata>
<f:viewParam name="examId" value="#{examBean.examNumber}"/>
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
</f:metadata>
<h:outputText value="#{examBean.examNumber}"/>
</h:form>
</h:body>
</html>
</f:view>
视图参数必须具有以下属性:
1- name :这是要从 url.
中获取的参数的名称
2- value :这是你要设置参数值的地方。
所以在我们的例子中名称是 "examId" 我们想在 "examBean.examNumber" 中设置值.
这里如果没有使用标签会发现一个问题,因为你想在postConstrct方法中获取examId onPage Load,但是f:param会在 postConstruct 之后调用,所以我们必须像下面这样使用 :
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
这将帮助我们在显示 JSF 页面之前执行自定义任务。
4- 在你的 examBean 中:
@ManagedBean(name = "examBean")
@RequestScoped
public class ExamBean {
public ExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public void onLoad () {
System.out.println("onLoad = "+getExamNumber());
}
}
请根据您的要求使用它,一切都会顺利进行。
请参考以下回答here, here and here。
希望对您有所帮助。
我想将 selectedExamId 从 chooseexam 页面传递到考试页面,这样做的好方法是什么?对单个 jsf 页面使用两个 baking bean 是一种好习惯吗?
还有一件事是我每次都得到相同的问题列表?
我有以下 jsf 页面
chooseExam.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">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<h:selectOneRadio value="#{examBean.selectedExamId}">
<f:selectItems value="#{chooseExamBean.exams}" var="exam" itemValue="#{exam.examId}" itemLabel="#{exam.examName}"/>
</h:selectOneRadio>
<h:commandButton value="Submit" action="/user/exam?faces-redirect=true"/>
</ui:define>
</ui:composition>
</h:body>
</html>
和
exam.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">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/admin/template.xhtml">
<ui:define name="content">
<ui:repeat value="#{examBean.questions}" var="question">
<h:outputLabel value="#{question.question}"/>
<h:selectOneRadio value="#{examBean.questionAnswerMap[question]}">
<f:selectItem itemValue="#{question.choice1}" itemLabel="#{question.choice1}"/>
<f:selectItem itemValue="#{question.choice2}" itemLabel="#{question.choice2}"/>
<f:selectItem itemValue="#{question.choice3}" itemLabel="#{question.choice3}"/>
<f:selectItem itemValue="#{question.choice4}" itemLabel="#{question.choice4}"/>
</h:selectOneRadio>
</ui:repeat>
<h:commandButton value="Submit" action="#{examBean.calculate}"/>
</ui:define>
</ui:composition>
</h:body>
</html>
以下是支持 bean
ChooseExamBean.java
@Component
@ManagedBean
public class ChooseExamBean {
List<Exam> exams;
@Autowired
private ExamService examService;
@PostConstruct
public void init(){
exams = examService.getAllExams();
}
public List<Exam> getExams() {
return exams;
}
public void setExams(List<Exam> exams) {
this.exams = exams;
}
}
和
ExamBean.java
@Component
@ManagedBean
public class ExamBean {
private List<Question> questions;
private Map<Question, String> questionAnswerMap = new HashMap<>();
private int score;
private Long selectedExamId;
@Autowired
private QuestionService questionService;
@PostConstruct
public void init() {
if(selectedExamId != null)
questions = questionService.getQuestionsForExam(selectedExamId);
}
public Map<Question, String> getQuestionAnswerMap() {
return questionAnswerMap;
}
public void setQuestionAnswerMap(Map<Question, String> questionAnswerMap) {
this.questionAnswerMap = questionAnswerMap;
}
public List<Question> getQuestions() {
if(questions == null)
questions = questionService.getQuestionsForExam(selectedExamId);
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public Long getSelectedExamId() {
return selectedExamId;
}
public void setSelectedExamId(Long selectedExamId) {
this.selectedExamId = selectedExamId;
}
public String calculate() {
score = questionAnswerMap.size();
return "result?faces-redirect=true";
}
}
由于您正在为(ExamBean 和 ChooseExamBean)使用 RequestScope Beans,您不能在响应后保留值,因此您应该使用 viewParam 标记将值从第一页传递到第二页。
你应该像下面这样:
1- ChooseExam.jsf ,您有将在 chooseExamBean 中保存其值的单选按钮:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<h:selectOneRadio label="examType" value="#{chooseExamBean.examNumber}">
<f:selectItem itemLabel="exam1" itemValue="1"/>
<f:selectItem itemLabel="exam2" itemValue="2"/>
</h:selectOneRadio>
<h:commandButton value="commandButton1" action="#{chooseExamBean.navigateToExamPage}" />
</h:form>
</h:body>
</html>
</f:view>
2- 在 commandButton 的操作中,您将调用 bean 中的方法进行导航,在导航之前,您将向 url 附加一个参数,例如navigateToExamPage 方法中的以下内容:
@ManagedBean(name = "chooseExamBean")
@RequestScoped
public class ChooseExamBean {
public ChooseExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public Object navigateToExamPage() {
return "exam?faces-redirect=true&examId="+getExamNumber();
}
}
3-在exam.jsf页面中,你必须获取参数的值,在这里你将使用标签,如下所示:
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
<h:form>
<f:metadata>
<f:viewParam name="examId" value="#{examBean.examNumber}"/>
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
</f:metadata>
<h:outputText value="#{examBean.examNumber}"/>
</h:form>
</h:body>
</html>
</f:view>
视图参数必须具有以下属性:
1- name :这是要从 url.
中获取的参数的名称2- value :这是你要设置参数值的地方。
所以在我们的例子中名称是 "examId" 我们想在 "examBean.examNumber" 中设置值.
这里如果没有使用标签会发现一个问题,因为你想在postConstrct方法中获取examId onPage Load,但是f:param会在 postConstruct 之后调用,所以我们必须像下面这样使用 :
<f:event type="preRenderView" listener="#{examBean.onLoad}" />
这将帮助我们在显示 JSF 页面之前执行自定义任务。
4- 在你的 examBean 中:
@ManagedBean(name = "examBean")
@RequestScoped
public class ExamBean {
public ExamBean() {
super();
}
private String examNumber;
public void setExamNumber(String examNumber) {
this.examNumber = examNumber;
}
public String getExamNumber() {
return examNumber;
}
public void onLoad () {
System.out.println("onLoad = "+getExamNumber());
}
}
请根据您的要求使用它,一切都会顺利进行。
请参考以下回答here, here and here。
希望对您有所帮助。