【问题标题】:Pass param from one jsf page to another将参数从一个 jsf 页面传递到另一个页面
【发布时间】:2016-01-24 09:58:37
【问题描述】:

我想将 selectedExamId 从选择考试页面传递到考试页面,这样做的好方法是什么?为单个 jsf 页面使用两个烘焙 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";
    }
}

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    由于您对(ExamBean 和 ChooseExamBean)使用 RequestScope Bean,因此您无法在响应后保留这些值,因此您应该使用 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 中的方法进行导航,在导航之前,您将在 navigateToExamPage 中将参数附加到 url,如下所示强>方法:

    @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-值:这是你要设置参数值的地方。

    所以在我们的例子中,名称是 "examId",我们想在 "examBean.examNumber" 中设置值。

    这里如果你没有使用标签你会发现一个问题,因为你想在postConstrct方法中获取examId onPage Load,但是在postConstruct之后会调用f:param,所以我们必须像下面这样使用

    <f:event type="preRenderView" listener="#{examBean.onLoad}" />
    

    这将帮助我们在显示 JSF 页面之前执行自定义任务。

    4- 在你的考试豆中:

    @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());
        }
    
    
    }
    

    请根据您的要求使用它,一切都会顺利进行。

    请参考下面的答案hereherehere

    希望有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2020-11-20
      相关资源
      最近更新 更多