`

第四章 Controller接口控制器详解(3)——跟着开涛学SpringMVC

阅读更多

4.11、AbstractWizardFormController

向导控制器类提供了多步骤(向导)表单的支持(如完善个人资料时分步骤填写基本信息、工作信息、学校信息等)

假设现在做一个完善个人信息的功能,分三个页面展示:

1、页面1完善基本信息;

2、页面2完善学校信息;

3、页面3完善工作信息。

这里我们要注意的是当用户跳转到页面2时页面1的信息是需要保存起来的,还记得AbstractFormController中的sessionForm吗? 如果为true则表单数据存放到session中,哈哈,AbstractWizardFormController就是使用了这个特性。


向导中的页码从0开始;

PARAM_TARGET = "_target"

用于选择向导中的要使用的页面参数名前缀,如“_target0”则选择第0个页面显示,即图中的“wizard/baseInfo”,以此类推,如“_target1”将选择第1页面,要得到的页码为去除前缀“_target”后的数字即是;

PARAM_FINISH = "_finish"

如果请求参数中有名为“_finish”的参数,表示向导成功结束,将会调用processFinish方法进行完成时的功能处理;

PARAM_CANCEL = "_cancel"

如果请求参数中有名为“_cancel”的参数,表示向导被取消,将会调用processCancel方法进行取消时的功能处理;

向导中的命令对象:

向导中的每一个步骤都会把相关的参数绑定到命令对象,该表单对象默认放置在session中,从而可以跨越多次请求得到该命令对象。

 

接下来具体看一下如何使用吧。

(1、修改我们的模型数据以支持多步骤提交: 

 

Java代码  
  1. public class UserModel {  
  2.     private String username;  
  3.     private String password;  
  4.     private String realname; //真实姓名  
  5.     private WorkInfoModel workInfo;  
  6.     private SchoolInfoModel schoolInfo;  
  7.     //省略getter/setter  
  8. }  

 

Java代码  
  1. public class SchoolInfoModel {  
  2.     private String schoolType; //学校类型:高中、中专、大学  
  3.     private String schoolName; //学校名称  
  4.     private String specialty; //专业  
  5. //省略getter/setter  
  6. }  

 

Java代码  
  1. public class WorkInfoModel {  
  2.     private String city; //所在城市  
  3.     private String job; //职位  
  4.     private String year; //工作年限  
  5. //省略getter/setter  
  6. }  

 

(2、控制器

 

Java代码  
  1. package cn.javass.chapter4.web.controller;  
  2. //省略import  
  3. public class InfoFillWizardFormController extends AbstractWizardFormController {      
  4.     public InfoFillWizardFormController() {  
  5.         setCommandClass(UserModel.class);  
  6.         setCommandName("user");  
  7.     }  
  8.     protected Map referenceData(HttpServletRequest request, int page) throws Exception {  
  9.         Map map = new HashMap();  
  10.         if(page==1) { //如果是填写学校信息页 需要学校类型信息  
  11.             map.put("schoolTypeList", Arrays.asList("高中", "中专", "大学"));  
  12.         }  
  13.         if(page==2) {//如果是填写工作信息页 需要工作城市信息  
  14.             map.put("cityList", Arrays.asList("济南", "北京", "上海"));  
  15.         }  
  16.         return map;  
  17.     }     
  18.     protected void validatePage(Object command, Errors errors, int page) {  
  19.         //提供每一页数据的验证处理方法  
  20.     }  
  21.     protected void postProcessPage(HttpServletRequest request, Object command, Errors errors, int page) throws Exception {  
  22.         //提供给每一页完成时的后处理方法  
  23.     }  
  24.     protected ModelAndView processFinish(HttpServletRequest req, HttpServletResponse resp, Object command, BindException errors) throws Exception {  
  25.         //成功后的处理方法  
  26.         System.out.println(command);  
  27.         return new ModelAndView("redirect:/success");  
  28.     }  
  29.     protected ModelAndView processCancel(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {  
  30.         //取消后的处理方法  
  31.         System.out.println(command);  
  32.         return new ModelAndView("redirect:/cancel");  
  33.     }  
  34. }  

 

page页码:是根据请求中以“_target”开头的参数名来确定的,如“_target0”,则页码为0;

referenceData提供每一页需要的表单支持对象,如完善学校信息需要学校类型,page页码从0开始(而且根据请求参数中以“_target”开头的参数来确定当前页码,如_target1,则page=1);

validatePage验证当前页的命令对象数据,验证应根据page页码来分步骤验证;

postProcessPage验证成功后的后处理;

processFinish成功时执行的方法,此处直接重定向到/success控制器(详见CancelController);

processCancel取消时执行的方法,此处直接重定向到/cancel控制器(详见SuccessController);

 

其他需要了解:

allowDirtyBack和allowDirtyForward决定在当前页面验证失败时,是否允许向导前移和后退,默认false不允许;

onBindAndValidate(HttpServletRequest request, Object command, BindException errors, int page)允许覆盖默认的绑定参数到命令对象和验证流程。

(3、spring配置文件(chapter4-servlet.xml

 

Java代码  
  1. <bean name="/infoFillWizard"   
  2. class="cn.javass.chapter4.web.controller.InfoFillWizardFormController">  
  3.     <property name="pages">  
  4.         <list>  
  5.             <value>wizard/baseInfo</value>  
  6.             <value>wizard/schoolInfo</value>  
  7.             <value>wizard/workInfo</value>  
  8.        </list>  
  9.     </property>  
  10. </bean>      

 

pages表示向导中每一个步骤的逻辑视图名,当InfoFillWizardFormController的page=0,则将会选择“wizard/baseInfo”,以此类推,从而可以按步骤选择要展示的视图。

 

(4、向导中的每一步视图

(4.1、基本信息页面(第一步) baseInfo.jsp 

 

Java代码  
  1. <form method="post">  
  2. 真实姓名:<input type="text" name="realname" value="${user.realname}"><br/>  
  3. <input type="submit" name="_target1" value="下一步"/>  
  4. </form>  

 

当前页码为0

name="_target1"表示向导下一步要显示的页面的页码为1;

 

(4.2、学校信息页面(第二步) schoolInfo.jsp

 

Java代码  
  1. <form method="post">  
  2. 学校类型:<select name="schoolInfo.schoolType">  
  3.   <c:forEach items="${schoolTypeList }" var="schoolType">  
  4.    <option value="${schoolType }"   
  5.        <c:if test="${user.schoolInfo.schoolType eq schoolType}">  
  6.            selected="selected"  
  7.        </c:if>  
  8.    >  
  9.        ${schoolType}  
  10.    </option>  
  11.   </c:forEach>  
  12. </select><br/>  
  13. 学校名称:<input type="text" name="schoolInfo.schoolName" value="${user.schoolInfo.schoolName}"/><br/>  
  14. 专业:<input type="text" name="schoolInfo.specialty" value="${user.schoolInfo.specialty}"/><br/>  
  15. <input type="submit" name="_target0" value="上一步"/>  
  16. <input type="submit" name="_target2" value="下一步"/>  
  17. </form>  

 

(4.3、工作信息页面(第三步) workInfo.jsp

 

Java代码  
  1. <form method="post">  
  2. 所在城市:<select name="workInfo.city">  
  3.   <c:forEach items="${cityList }" var="city">  
  4.    <option value="${city }"   
  5.        <c:if test="${user.workInfo.city eq city}">selected="selected"</c:if>  
  6.    >  
  7.      ${city}  
  8.    </option>  
  9.   </c:forEach>  
  10. </select><br/>  
  11. 职位:<input type="text" name="workInfo.job" value="${user.workInfo.job}"/><br/>  
  12. 工作年限:<input type="text" name="workInfo.year" value="${user.workInfo.year}"/><br/>  
  13. <input type="submit" name="_target1" value="上一步"/>  
  14. <input type="submit" name="_finish" value="完成"/>  
  15. <input type="submit" name="_cancel" value="取消"/>  
  16. </form>  

 

当前页码为2

name="_target1":上一步,表示向导上一步要显示的页面的页码为1;

name="_finish":向导完成,表示向导成功,将会调用向导控制器的processFinish方法

name="_cancel":向导取消,表示向导被取消,将会调用向导控制器的processCancel方法

 

到此向导控制器完成,此处的向导流程比较简单,如果需要更复杂的页面流程控制,可以选择使用Spring Web Flow框架。

 

4.12、ParameterizableViewController

参数化视图控制器,不进行功能处理(即静态视图),根据参数的逻辑视图名直接选择需要展示的视图。 

 

Java代码  
  1. <bean name="/parameterizableView"   
  2. class="org.springframework.web.servlet.mvc.ParameterizableViewController">  
  3. <property name="viewName" value="success"/>  
  4. </bean>  

 

该控制器接收到请求后直接选择参数化的视图,这样的好处是在配置文件中配置,从而避免程序的硬编码,比如像帮助页面等不需要进行功能处理,因此直接使用该控制器映射到视图。

4.13、AbstractUrlViewController

提供根据请求URL路径直接转化为逻辑视图名的支持基类,即不需要功能处理,直接根据URL计算出逻辑视图名,并选择具体视图进行展示:

urlDecode是否进行url解码,不指定则默认使用服务器编码进行解码(如Tomcat默认ISO-8859-1);

urlPathHelper用于解析请求路径的工具类,默认为org.springframework.web.util.UrlPathHelper。

 

UrlFilenameViewController是它的一个实现者,因此我们应该使用UrlFilenameViewController。

 

4.14、UrlFilenameViewController

将请求的URL路径转换为逻辑视图名并返回的转换控制器,即不需要功能处理,直接根据URL计算出逻辑视图名,并选择具体视图进行展示:

 

根据请求URL路径计算逻辑视图名; 

 

Java代码  
  1. <bean name="/index1/*"   
  2. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  3. <bean name="/index2/**"   
  4. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  5. <bean name="/*.html"   
  6. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  
  7. <bean name="/index3/*.html"   
  8. class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>  

 

/index1/*可以匹配/index1/demo,但不匹配/index1/demo/demo,如/index1/demo逻辑视图名为demo;

/index2/**可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2/demo/demo,“/index2/demo”的逻辑视图名为demo,而“/index2/demo/demo”逻辑视图名为demo/demo;

/*.html可以匹配如/abc.html,逻辑视图名为abc,后缀会被删除(不仅仅可以是html);

/index3/*.html可以匹配/index3/abc.html,逻辑视图名也是abc;

 

上述模式为Spring Web MVC使用的Ant-style 模式进行匹配的:

 

Java代码  
  1. ?    匹配一个字符,如/index? 可以匹配 /index1 , 但不能匹配 /index 或 /index12  
  2. *    匹配零个或多个字符,如/index1/*,可以匹配/index1/demo,但不匹配/index1/demo/demo 
  3. **   匹配零个或多个路径,如/index2/**:可以匹配/index2路径下的所有子路径,如匹配/index2/demo,或/index2/demo/demo 
  4.  
  5. 如果我有如下模式,那Spring该选择哪一个执行呢?当我的请求为“/long/long”时如下所示: 
  6. /long/long 
  7. /long/**/abc  
  8. /long/** 
  9. /** 
  10. Spring的AbstractUrlHandlerMapping使用:最长匹配优先; 
  11. 如请求为“/long/long” 将匹配第一个“/long/long”,但请求“/long/acd” 则将匹配 “/long/**”,如请求“/long/aa/abc”则匹配“/long/**/abc”,如请求“/abc”则将匹配“/**”  

 

UrlFilenameViewController还提供了如下属性:

prefix生成逻辑视图名的前缀;

suffix生成逻辑视图名的后缀;

 

Java代码  
  1. protected String postProcessViewName(String viewName) {  
  2.         return getPrefix() + viewName + getSuffix();  
  3. }  

 

Java代码  
  1. <bean name="/*.htm" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">  
  2.         <property name="prefix" value="test"/>  
  3.         <property name="suffix" value="test"/>  
  4. </bean>  

 

prefix=“test”,suffix=“test,如上所示的/*.htm可以匹配如/abc.htm,但逻辑视图名将变为testabctest。

 


私塾在线学习网
原创内容(http://sishuok.com

原创内容,转载请注明私塾在线【http://sishuok.com/forum/blogPost/list/5254.html

原文地址:http://jinnianshilongnian.iteye.com/blog/1622684

原作者:开涛

如有侵权请通知我删除!!!

JAVA技术交流群 532101200

分享到:
评论

相关推荐

    源代码下载 第五章 处理器拦截器详解——跟着开涛学SpringMVC

    NULL 博文链接:https://jinnianshilongnian.iteye.com/blog/1679570

    跟着开涛学SpringMVC

    跟着开涛学SpringMVC,很好的MVC教程,简单易懂,PDF高清版本

    SpringMvc开涛.rar

    PDF,源代码 开涛学SpringMVC 第一章源...第四章 Controller接口控制器详解 源代码下载 第五章 处理器拦截器详解——跟着开涛学SpringMVC 第六章 注解式控制器详解 第七章 注解式控制器的数据验证、类型转换及格式化

    跟着开涛学SpringMVC.pdf

    跟开涛学springmvc pdf电子文档版 适合学习springmvc 非常好的教程

    跟我学SpringMVC 教程

    第四章 Controller接口控制器详解(4) 第四章 Controller接口控制器详解(5) 第四章 Controller接口控制器详解(6) 第五章 处理器拦截器详解 第六章 注解式控制器详解 注解式控制器运行流程及处理器定义 第...

    跟开涛学 SpringMVC

    跟开涛学 SpringMVC跟开涛学 SpringMVC跟开涛学 SpringMVC跟开涛学 SpringMVC

    跟我学SpringMVC

    第四章 Controller接口控制器详解(4) 第四章 Controller接口控制器详解(5) 第四章 Controller接口控制器详解(6) 第五章 处理器拦截器详解 第六章 注解式控制器详解 注解式控制器运行流程及处理器定义 第六章 ...

    SpringMVC教程

    第四章 Controller接口控制器详解(3).pdf 第四章 Controller接口控制器详解 (4).pdf 第四章 Controller接口控制器详解 (5).pdf 第四章 Controller接口控制器详解 (6).pdf 第四章 Controller接口控制器详解...

    跟开涛学SpringMVC-高清版

    跟开涛学SpringMVC-高清版,找了好久的,分享给大家。

    Spring MVC学习(四)-------Controller接口控制器详解1

    Spring MVC学习(四)-------Controller接口控制器详解1

    跟开涛学SpringMVC(4.6)Controller接

    跟开涛学SpringMVC(4.6)Controller接口控制器详解(6)Java开发Java经验技巧共10页.pdf.zip

    跟开涛学SpringMVC源代码

    跟开涛学SpringMVC源代码汇总

    跟开涛学SpringMVC

    跟开涛学SpringMVC 高清 带书签 pdf 通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText和POI。Spring MVC 框架并不知道使用的视图,所以...

    跟开涛学SpringMVC(4.3)Controller接

    跟开涛学SpringMVC(4.3)Controller接口控制器详解(3)Java开发Java经验技巧共9页.pdf.zip

    跟开涛学习springmvc spring 3 pdf

    跟开涛学习springmvc spring 3 pdf ,非常好的资料。我将原文档的spring合并为一份,查看更方便一些。

    跟开涛学springmvc

    开涛写的中文springmvc开发文档 , 初学者可以下载学习,或者当做字典用。

    跟开涛学SpringMVC(5)处理器拦截器详解Java开

    跟开涛学SpringMVC(5)处理器拦截器详解Java开发Java经验技巧共13页.pdf.zip

    SpringMVC入门——跟开涛学SpringMVC

    SpringWebMVC是一种基于Java的实现了WebMVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行...应用控制器其实拆为处理器映射器(HandlerMapping)进行处理器管理和视图解析器(ViewResolv

Global site tag (gtag.js) - Google Analytics