org.springframework.web.servlet.mvc.AbstractWizardFormController
可以讓您設計出如桌面應用程式的精靈(Wizard),通常用於問卷表單內容相當長時,與其使用一個表單呈現所有的問卷內容,不如將問卷內容分作數個畫
面,讓使用者一頁一頁完成問卷,您可以繼承AbstractWizardFormController,並重新定義它的processFinish()方
法,當中定義的是全部問卷提交完後的處理,例如:
package onlyfun.caterpillar;
import java.util.*; import javax.servlet.http.*; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet. mvc.AbstractWizardFormController; import org.springframework.validation.BindException;
public class WizardController extends AbstractWizardFormController { private String successView; public WizardController() { setCommandClass(Questionnaire.class); } protected ModelAndView processFinish( HttpServletRequest request, HttpServletResponse response, Object command, BindException exception) throws Exception { Questionnaire questionnaire = (Questionnaire) command; Map model = new HashMap(); model.put("q1", questionnaire.getQuestion1()); model.put("q2", questionnaire.getQuestion2()); model.put("q3", questionnaire.getQuestion3()); return new ModelAndView(getSuccessView(), "ans", model); } public void setSuccessView(String successView) { this.successView = successView; } public String getSuccessView() { return successView; } }
所有的問卷結果收集在一個Command物件中,上面的程式只是將結果取得並設定在Model資料物件中,以在View上呈現資料,Command的類別設計如下:
package onlyfun.caterpillar;
public class Questionnaire { private String question1; private String question2; private String question3; public void setQuestion1(String question1) { this.question1 = question1; } public void setQuestion2(String question2) { this.question2 = question2; } public void setQuestion3(String question3) { this.question3 = question3; } public String getQuestion1() { return question1; } public String getQuestion2() { return question2; } public String getQuestion3() { return question3; } }
問卷的流程是規範在Bean定義檔中,藉由設定AbstractWizardFormController的"pages"屬性來決定,例如:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <bean id="urlMapping" class="org.springframework.web.servlet. → handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/wizard.do">wizardController</prop> </props> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean>
<bean id="wizardController" class="onlyfun.caterpillar.WizardController"> <property name="successView"> <value>success</value> </property> <property name="pages"> <list> <value>start</value> <value>question1</value> <value>question2</value> <value>question3</value> </list> </property> </bean> </beans>
依以上的設定,問卷將依start.jsp、question1.jsp、question2.jsp、question3.jsp的順序來完成,首先看看start.jsp的撰寫:
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Start Page</title> </head> <body> <form name="questionform" action="/AbstractWizardDemo/wizard.do" method="POST"> 歡迎您填寫問卷! <input type="submit" value="Start" name="_target1"/> </form> </body> </html>
當您連接至Wizard控制器時,預設會取得設定檔中索引0位置的網頁來顯示,第一個頁面通常是歡迎或問卷說明頁面,決定下一個要展示的頁面之方法,在於
請求中有無帶有一個"_target"開頭,並跟著一個號碼的請求參數,例如"_target1"這樣的設定,號碼表示在設定檔中<
list>的順序,上面的網頁在按下Start按鈕後,會顯示第二個頁面:
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Question 1</title> </head> <body> <form name="questionform1" action="/AbstractWizardDemo/wizard.do" method="POST"> 問題一 <input type="text" name="question1"/><br> <input type="submit" value="Previous" name="_target0"/> <input type="submit" value="Next" name="_target2"/> </form> </body> </html>
依"_target"與號碼來決定顯示的頁面是getTaretPage()方法所預設的,必要的話,您也可以重新定義這個方法以決定下一個頁面由哪一個
參數決定,在question1.jsp的設計中,按下Previous按鈕的話,會返回問卷的上一頁,按下Next的按鈕的話,會返回問卷的下一頁,
question2.jsp的設計也是類似。
決定是否完成問卷的方式,在於檢驗請求中是否有請求參數"_finish",如果檢查到有這個值,就會執行processFinish()方法,question3.jsp是最後一個問卷,來看看它是如何撰寫的:
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Question 3</title> </head> <body>
<form name="questionform3" action="/AbstractWizardDemo/wizard.do" method="POST"> 問題三 <input type="text" name="question3"/><br> <input type="submit" value="Previous" name="_target2"/> <input type="submit" value="Finish" name="_finish"/> </form> </body> </html>
記得最後一個送出的問卷要帶有一個"_finish"參數,才會執行AbstractWizardFormControlle的processFinish()方法,最後設計一個success.jsp來顯示結果:
<%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Success</title> </head> <body> <H1>Q1: ${ans.q1}</H1> <br> <H1>Q2: ${ans.q2}</H1> <br> <H1>Q3: ${ans.q3}</H1> <br> </body> </html>
您也可以在問卷中設計一個Cancel按鈕,在按下該按鈕後,可以送出"_cancel"請求參數,例如:
....
<form name="questionform3"
action="/AbstractWizard/wizard.do" method="POST">
....
<input type="submit" value="Cancel" name="_cancel"/>
</form>
....
當請求中帶有"_cancel"請求參數時,則會呼叫processCancel()方法,您可以重新定義這個方法,例如將使用者送回問卷開始時:
...
protected ModelAndView processFinish(
HttpServletRequest request,
HttpServletResponse response,
Object command,
BindException exception) throws Exception {
return new ModelAndView("start");
}
...
|