Spring MVC学习指南.docx
- 文档编号:12710837
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:22
- 大小:208.73KB
Spring MVC学习指南.docx
《Spring MVC学习指南.docx》由会员分享,可在线阅读,更多相关《Spring MVC学习指南.docx(22页珍藏版)》请在冰豆网上搜索。
SpringMVC学习指南
SpringMVC学习指南
以下这个学习案例是我最近学习SpringMVC时跟从一本书上的示例,原文中的示例代码有一些小错误,不过我在调试的过程中已经给予了修正,如还有其它错误,还请各位批评指正。
对于现有较成熟的Model-View-Control(MVC)框架而言,其解决的主要问题无外乎下
面几部分:
1.将Web页面中的输入元素封装为一个(请求)数据对象。
2.根据请求的不同,调度相应的逻辑处理单元,并将(请求)数据对象作为参数传入。
3.逻辑处理单元完成运算后,返回一个结果数据对象。
4.将结果数据对象中的数据与预先设计的表现层相融合并展现给用户。
各个MVC实现固然存在差异,但其中的关键流程大致如上。
结合一个实例,我们来看看这
几个关键流程在SpringMVC框架中的处理手法。
下面的实例,实现了一个常见的用户登录逻辑,即用户通过用户名和密码登录,系统对用
户名和密码进行检测,如果正确,则在页面上显示几条通知信息。
如果登录失败,则返回失败
界面。
(示例中,表示层以JSP2.0实现。
)
出于简洁考虑,这里的“用户名/密码”检测以及通知信息的生成均在代码中以硬编码实现。
首先来看登录界面:
对应的index.html:
用户名:
密码:
很简单的一个登录界面,其中包含了一个用以输入用户名密码的form,针对此form的提
交将被发送到"login.do"
MVC关键流程的第一步,即收集页面输入参数,并转换为请求数据对象。
这个静态页面提
供了一个基本的输入界面,下面这些输入的数据将被发送至何处,将如何被转换为请求数据对
象?
现在来看接下来发发生的事情:
当用户输入用户名密码提交之后,此请求被递交给Web服务器处理,上面我们设定form
提交目标为"login.do",那么Web服务器将如何处理这个请求?
显然,标准Http协议中,并没有以.do为后缀的服务资源,这是我们自己定义的一种请
求匹配模式。
此模式在web.xml中设定:
xmlversion="1.0"encoding="ISO-8859-1"?
>
xmlns: xsi="nstance" xsi: schemaLocation=" " version="2.4"> org.springframework.web.servlet.DispatcherServlet ⑴Servlet定义 这里我们定义了请求分发Servlet,即: org.springframework.web.servlet.DispatcherServlet DispatcherServlet是SpringMVC中负责请_____求调度的核心引擎,所有的请求将 由此Servlet根据配置分发至各个逻辑处理单元。 其内部同时也维护了一个 ApplicationContext实例。 我们在 Servlet参数,此参数指定了Spring配置文件的位置“/WEB-INF/Config.xml”。 如果忽略此设定,则默认为“/WEB-INF/ 中 “/WEB-INF/Dispatcher-servlet.xml)。 ⑵请求映射 我们将所有以.do结尾的请求交给SpringMVC进行处理。 当然,也可以设为其他值, 如.action、.action等。 通过以上设定,Web服务器将把登录界面提交的请求转交给Dispatcher处理, Dispatcher将提取请求(HttpServletRequest)中的输入数据,分发给对应的处理单元, 各单元处理完毕后,将输出页面返回给Web服务器,再由Web服务器返回给用户浏览器。 Dispatcher根据什么分发这些请求? 显然,我们还需要一个配置文件加以设定。 这也就 是上面提及的Config.xml,此文件包含了所有的“请求/处理单元”关系映射设定,以及返回 时表现层的一些属性设置。 xmlversion="1.0"encoding="UTF-8"? > DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN" ""> --DefinitionofViewResolver--> class="org.springframework.web.servlet.view.InternalResou rceViewResolver"> org.springframework.web.servlet.view.JstlView /WEB-INF/view/ --RequestMapping--> class="org.springframework.web.servlet.handler.SimpleUr lHandlerMapping"> ---ActionDefinition--> class="net.xiaxin.action.LoginAction"> ⑴Resolver设定 Resolver将把输出结果与输出界面相融合,为表现层提供呈现资源。 ⑵ViewResolver的viewClass参数 这里我们使用JSP页面作为输出,因此,设定为: org.springframework.web.servlet.view.JstlView 其余可选的viewClass还有: Øorg.springframework.web.servlet.view.freemarker.FreeMarker View(用于基于FreeMarker模板的表现层实现) Øorg.springframework.web.servlet.view.velocity.VelocityView (用于基于velocity模板的表现层实现) 等。 ⑶⑷ViewResolver的prefix和suffix参数 指定了表现层资源的前缀和后缀,运行时,Spring将为指定的表现层资源自动追加 前缀和后缀,以形成一个完整的资源路径。 另参见⑻ ⑸“请求/处理单元”关系映射 可以看到,这里我们将“/login.do”请求映射到处理单元LoginAction。 ⑹LoginAction定义 这里定义了逻辑处理单元LoginAction的具体实现,这里,LoginAction的实现 类为net.xiaxin.action.LoginAction。 ⑺LoginAction的请求数据对象 commandClass参数源于LoginAction的基类BaseCommandController, BaseCommandControlle包含了请求数据封装和验证方法 (BaseCommandController.bindAndValidate),它将根据传入的 HttpServletRequest构造请求数据对象。 这里我们指定commandClass为net.xiaxin.action.LoginInfo,这是一个非 常简单的JavaBean,它封装了登录请求所需的数据内容: publicclassLoginInfo{ privateStringusername; privateStringpassword; publicStringgetPassword(){ returnpassword; } publicvoidsetPassword(Stringpassword){ this.password=password; } publicStringgetUsername(){ returnusername; } publicvoidsetUsername(Stringusername){ this.username=username; } } Spring会根据LoginAction的commandClass定义自动加载对应的LoginInfo 实例。 之后,对Http请求中的参数进行遍历,并查找LoginInfo对象中是否存在与之同 名的属性,如果找到,则将此参数值复制到LoginInfo对象的同名属性中. 请求数据转换完成之后,我们得到了一个封装了所有请求参数的Java对象,并将此 对象作为输入参数传递给LoginAction。 ⑻返回视图定义 对于这里的LoginAction而言,有两种返回结果,即登录失败时返回错误界面,登 录成功时进入系统主界面。 对应我们配置了fail_view、success_view两个自定义参数。 参数值将由Resolver进行处理,为其加上前缀后缀,如对于fail_view而言,实 际的视图路径为/WEB-INF/view/loginfail.jsp。 之后,Resolver会将LoginAction的返回数据与视图相融合,返回最终的显示界 面。 业务逻辑处理单元: LoginAction.java: publicclassLoginActionextendsSimpleFormController{ privateStringfail_view; privateStringsuccess_view; protectedModelAndViewonSubmit(⑴ Objectcmd, BindExceptionex )throwsException{ LoginInfologinInfo=(LoginInfo)cmd;⑵ HashMapresult_map=newHashMap(); if(login(loginInfo)==0){ result_map.put("logininfo",loginInfo); ListmsgList=newLinkedList(); msgList.add("msg1"); msgList.add("msg2"); msgList.add("msg3"); result_map.put("messages",msgList); returnnew ModelAndView(this.getSuccess_view(),result_map);⑶ }else{ result_map.put("failmsg",newString("Sorry,youinputthewrongusernameorpassword! ")); returnnewModelAndView(this.getFail_view(),result_map); } } privateintlogin(LoginInfologinInfo){ if("Erica".equalsIgnoreCase(loginInfo.getUsername()) &&"mypass".equals(loginInfo.getPassword())){ return0; } return1; } publicStringgetFail_view(){ returnfail_view; } publicStringgetSuccess_view(){ returnsuccess_view; } publicvoidsetFail_view(Stringstring){ fail_view=string; } publicvoidsetSuccess_view(Stringstring){ success_view=string; } } 其中: ⑴onSubmit方法 我们在子类中覆盖了父类的onSubmit方法;而onSubmit方法用于处理业务请求。 负责数据封装和请求分发的Dispatcher,将对传入的HttpServletRequest进行 封装,形成请求数据对象,之后根据配置文件,调用对应业务逻辑类的入口方法(这 里就是LoginAction)的onSubmit()方法,并将请求数据对象及其他相关资源引 用传入。 protectedModelAndViewonSubmit( Objectcmd, BindExceptionex ) onSubmit方法包含了两个参数: Objectcmd和BindExceptionex。 前面曾经多次提到请求数据对象,这个名为cmd的Object型参数,正是传入的请求 数据对象的引用。 BindExceptionex参数则提供了数据绑定错误的跟踪机制。 它作为错误描述工具, 用于向上层反馈错误信息。 在SpringMVC中,BindException将被向上层表现层反馈,以便在表现层统一处 理异常情况(如显示对应的错误提示),这一机制稍后在“输入参数合法性校验”部 分再具体探讨。 onSubmit还有另外一个签名版本: protectedModelAndViewonSubmit( HttpServletRequestrequest, HttpServletResponseresponse, Objectcmd, BindExceptionex ) 可以看到,类似Servlet的doGet/doPost方法,此版本的onSubmit方法签名中 包含了Servlet规范中的HttpServletRequest、HttpServletResponse以提 供与Web服务器的交互功能(如Session的访问)。 此参数类型的onSubmit方法 的调用优先级较高。 也就是说,如果我们在子类中同时覆盖了这两个不同参数的 onSubmit方法,那么只有此版本的方法被执行,另一个将被忽略。 ⑵将输入的请求数据对象强制转型为预定义的请求对象类型。 ⑶返回处理结果 ModelAndView类包含了逻辑单元返回的结果数据集和表现层信息。 ModelAndView 本身起到关系保存的作用。 它将被传递给Dispatcher,由Dispatcher根据其中 保存的结果数据集和表现层设定合成最后的界面。 这里我们用到了两种签名版本的ModelAndView构造方法: ØpublicModelAndView(Stringviewname) 返回界面无需通过结果数据集进行填充。 ØpublicModelAndView(Stringviewname,Mapmodel) 返回界面由指定的结果数据集加以填充。 可以看到,结果数据集采用了Map接口 实现的数据类型。 其中包含了返回结果中的各个数据单元。 关于结果数据集在界 面中的填充操作,可参见下面关于返回界面的描述。 上面这两个版本的构造子中,通过viewname指定了表示层资源。 另外,我们也可以通过传递View对象指定表示层资源。 ØpublicModelAndView(Viewview) ØpublicModelAndView(Viewview,Mapmodel) 我们可以结合RedirectView完成转向功能,如: returnnewModelAndView( newRedirectView(“/redirected.jsp” )); 当然,我们也可以在带有HttpServletRequest参数的onSubmit方法实现中,通 过HttpServletRequest/HttpServletResponse完成forward/redirect功 能,这两种途径可以达到同样的效果。 最后,来看返回界面: 错误返回界面loginfail.jsp只是个纯html文件(为了与ViewResolver中设 定的后缀相匹配,因此以.jsp作为文件后缀),这里就不再浪费篇幅。 再看成功登录后的页面main.jsp: 界面显示效果如下: <%@taglibprefix="c"uri=""%> LoginSuccess! ! ! CurrentUser: outvalue="${logininfo.username}"/> Yourcurrentmessages: forEachitems="${messages}" var="item" begin="0" end="9" step="1" varStatus="var"> iftest="${var.index%2==0}"> * if> ${item} forEach> 登录失败后的页面loginfail.jsp: <%@taglibprefix="c"uri=""%>
LoginFail!
!
!
outvalue="${failmsg}"/>
页面逻辑非常简单,首先显示当前登录用户的用户名。
然后循环显示当前用户的通知消息
“messages”。
如果当前循环索引为奇数,则在消息前追加一个“*”号(这个小特性在这里
似乎有些多余,但却为不熟悉JSTL的读者提供了如何使用JSTLCoretaglib进行循环和
逻辑判断的样例)。
实际上这只是个普通JSTL/JSP页面,并没有任何特殊之处,如果说有些值得研究的技术,
也就是其中引用的JSTLCoreTaglib
<%@taglibprefix="c"uri=""%>
上面这句话申明了页面中所引用的taglib,指定其前缀为“c”,也就是说,在页面中,
所有以“c”为前缀,形同 xxxx>的节点都表明是此taglib的引用,在这里,也就是对JSTL CoreLib的引用。 这里需要注意的是,笔者所采用的Web容器为Tomcat5(支持Servlet2.4/JSP2.0 规范)以及ApacheJSTL2.0()。 outvalue="${logininfo.username}"/> out>将value中的内容输出到当前位置,这里也就是把logininfo对象的 username属性值输出到页面当前位置。 ${……}是JSP2.0中的ExpressionLanguage(EL)的语法。 它定义了一个表达式, 其中的表达式可以是一个常量(如上),也可以是一个具体的表达语句(如forEach循环体中 的情况)。 典型案例如下: Ø${logininfo.username} 这表明引用logininfo对象的username属性。 我们可以通过“.”操作符引 用对象的属性,也可以用“[]”引用对象属性,如${logininfo[username]} 与${logininfo.username}达到了同样的效果。 “[]”引用方式的意义在于,如果属性名中出现了特殊字符,如“.”或者“-”, 此时就必须使用“[]”获取属性值以避免语法上的冲突(系统开发时应尽量避免 这一现象的出现)。 与之等同的JSPScript大致如下: LoginInfologininfo= (LoginInfo)session.getAttribute(“logininfo”); Stringusername=logininfo.getUsername(); 可以看到,EL大大节省了编码量。 这里引出的另外一个问题就是,EL将从哪里找到logininfo对象,对于 ${logininfo.username}这样的表达式而言,首先会从当前页面中寻找之前是 否定义了变量logininfo,如果没有找到则依次到Request、Session、 Application范围内寻找,直到找到为止。 如果直到最后依然没有找到匹
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring MVC学习指南 MVC 学习指南
![提示](https://static.bdocx.com/images/bang_tan.gif)