将参数从一个 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

希望对您有所帮助。