SpringMVC入门实例及详细讲解

SpringServletWebBeanMVC

      Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架。通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer PagesJSP)技术、VelocityTilesiText POISpring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
  Spring Web MVC 框架是围绕 DispatcherServlet 设计的,它把请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上载文件支持。默认的处理程序是非常简单的 Controller 接口,只有一个方法 ModelAndView handleRequest(request, response)Spring 提供了一个控制器层次结构,可以派生子类。如果应用程序需要处理用户输入表单,那么可以继承 AbstractFormController。如果需要把多页输入处理到一个表单,那么可以继承 AbstractWizardFormController

     Spring MVC对于现在较成熟的Model-View-Control框架而言,其解决的主要问题无外乎下面几部分:
     1》将web页面中的输入元素封装为一个(请求)数据对象。
     2》根据请求的不同,调度相应的逻辑处理单元,并将(请求)数据对象作为参数传入。
     3》逻辑处理单元完成运算后,返回一个结果数据对象。
     4》将结果数据对象中的数据与预先设计的表现层相融合并展现给用户。
开发步骤:

 首先新建web Project项目:MySpringMvc

1.加载项目所需要的jar包;
   spring.jar -------------------------这个在spring2.5.6资源包的dist下面
   spring-webmvc.jar---------------这个在spring2.5.6资源包的dist/module下面

2.配置web.xml文件

 <?xml version="1.0" encoding="UTF-8"?>

Xml代码  

1.  <SPAN style="FONT-SIZE: large"><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  

2.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

3.      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    

4.      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  

5.      <servlet>  

6.          <servlet-name>dd</servlet-name>  

7.          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  

8.          <!--     <init-param>-->  

9.          <!--         <param-name>contextConfigLocation</param-name>-->  

10.         <!--         <param-value>/WEB-INF/applicationContext.xml</param-value>-->  

11.         <!--             </init-param>-->  

12.     </servlet>  

13.     <!--   

14.         applicationContext.xml文件代表示应用程序服务的配置和 bean 配置。如果想装入多个配置文件,可以在   

15.         <param-value>标记中用逗号作分隔符。   

16.         springmvc配置文件与spring配置的servlet名称有关[如本配置中是dd]   

17.         通常springmvc配置文件名称结构为:[servlet-name]-servlet.xml   

18.         如果你没有指定init-param里面contextCofigLocation的值中对应的XML文件的话   

19.         (也就是applicationContext全局配置文件没有配置在web.xml中的话),那么像本   

20.         段代码对应在springmvc中的配置文件就应该是/WEB-INF/dipatcher-servlet.xml这样的文件,   

21.         否则如果配置了applicaitonContext.xml这样的spring全局配置文件,如本配置那么就必须为/WEB-INF/dd-servlet.xml   

22.     -->  

23.     <servlet-mapping>  

24.         <servlet-name>dd</servlet-name>  

25.         <url-pattern>*.do</url-pattern>  

26.     </servlet-mapping>  

27. </web-app></SPAN>  

2.由于上面的初始化参数中没有指定名字的XML文件,因此在WEB-INF下面建立

  dispatcher-servlet.xml 

Xml代码  

1.  <SPAN style="FONT-SIZE: medium"><SPAN style="FONT-SIZE: large"><?xml version="1.0" encoding="UTF-8"?>  

2.  <!--看到下面的beans这个元素标签没有,必须有标签的声明-->  

3.  <beans  

4.      xmlns="http://www.springframework.org/schema/beans"  

5.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

6.      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">  

7.    

8.  <!-- URL Mapping -->  

9.  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  

10.     <property name="mappings">  

11.         <props>  

12.             <prop key="/regAction.do">regAction</prop>  

13.         </props>  

14.     </property>  

15. </bean>  

16.   

17. <!-- definition of View Resolver -->  

18. <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  

19.     <property name="viewClass">  

20.         <value>org.springframework.web.servlet.view.JstlView</value>  

21.     </property>  

22.     <property name="prefix">  

23.         <value>/view/</value>  

24.     </property>  

25.     <property name="suffix">  

26.         <value>.jsp</value>  

27.     </property>  

28. </bean>  

29. <!-- formController ,这个formController可以配置也可以不配置-->  

30.  <bean id="formController"  

31.  class="org.springframework.web.servlet.mvc.ParameterizableViewController">  

32.   <property name="viewName">  

33.    <value>form</value>  

34.   </property>  

35.  </bean>  

36.   

37. <!-- Action Definition -->  

38. <bean id="regAction" class="org.lee.springmvc.demo.RegAction">  

39. <!--MySpringMvc这个项目中就没有配置这个commandClass,   

40. 因为它提前调用了setCommandClass(LoginForm.class)这个方法;这样跟下面效果一样   

41. 不过还是建议配成下面这样的更好   

42. -->  

43.     <property name="commandClass">  

44.         <value>org.lee.springmvc.demo.RegInfo</value>  

45.     </property>  

46.     <property name="error_view">  

47.         <value>error</value>  

48.     </property>  

49.     <property name="success_view">  

50.         <value>success</value>  

51.     </property>  

52.     <property name="commandName">  

53.         <value>myCommand</value>  

54.     </property>  

55. </bean>  

56. </beans></SPAN></SPAN>  

 3.建立JSP文件

form.jsp

Html代码  

1.  <SPAN style="FONT-SIZE: medium"><SPAN style="FONT-SIZE: large"><%@page contentType="text/html"%>  

2.  <%@page pageEncoding="UTF-8"%>  

3.  <%@taglib prefix="spring"    

4.                   uri="http://www.springframework.org/tags"%>  

5.                      

6.  <%@taglib prefix="c"    

7.                   uri="http://java.sun.com/jsp/jstl/core"%>  

8.  <html>  

9.      <head>  

10.         <meta http-equiv="Content-Type"    

11.               content="text/html; charset=UTF-8">  

12.         <title>Login Form</title>  

13.     </head>  

14.     <body>  

15.     <h1>登入表单</h1>  

16.     <spring:bind path="command.*">    

17.         <font color="red">  

18.             <b>${status.errorMessage}</b>  

19.         </font><br>    

20.     </spring:bind>    

21.        

22.     请输入使用者名称与密码:<p>    

23.     <form name="loginform" action="login.do" method="post">    

24.        

25.         <spring:bind path="command.userName">    

26.         名称 <input type="text" name="${status.expression}" value="${status.value}"/>  

27.             <font color="red"><c:out value="${status.errorMessage}" /></font><br/>  

28.            

29.         </spring:bind>    

30.        

31.         <spring:bind path="command.password">    

32.         密码 <input type="password" name="${status.expression}" value="${status.value}"/>  

33.          <font color="red"><c:out value="${status.errorMessage}" /></font><br/>  

34.         </spring:bind>    

35.        

36.         <input type="submit" value="确定"/>    

37.     </form>    

38.     注意:输入错误会再回到这个页面中。         

39.     </body>  

40. </html></SPAN></SPAN>  

 4.建立jsp文件
success.jsp

Html代码  

1.  <SPAN style="FONT-SIZE: medium"><SPAN style="FONT-SIZE: large"><%@page contentType="text/html"%>  

2.  <%@page pageEncoding="GBK"%>  

3.    

4.  <html>  

5.      <head>  

6.          <meta http-equiv="Content-Type" content="text/html; charset=GBK">  

7.          <title>登入成功</title>  

8.      </head>  

9.      <body>  

10.         <H1>哈啰! ${welcomeuser}!!</H1>    

11.         这是您的神秘礼物!^o^<a href="login.do">退出登录</a>  

12.     </body>  

13. </html></SPAN></SPAN>  

 

 5.建立一个java bean LoginForm.java

Java代码  

1.  <SPAN style="FONT-SIZE: medium"><SPAN style="FONT-SIZE: large">package zz.it.beans;   

2.    

3.  public class LoginForm {   

4.      private String userName;   

5.      private String password;   

6.    

7.      public String getPassword() {   

8.          return password;   

9.      }   

10.   

11.     public void setPassword(String password) {   

12.         this.password = password;   

13.     }   

14.   

15.     public String getUserName() {   

16.         return userName;   

17.     }   

18.   

19.     public void setUserName(String userName) {   

20.         this.userName = userName;   

21.     }   

22.   

23.        

24. }   

25. </SPAN></SPAN>  

6.建立controller LoginController.java

Java代码  

1.  <SPAN style="FONT-SIZE: medium"><SPAN style="FONT-SIZE: large">package zz.it.controller;   

2.    

3.    

4.  import org.springframework.validation.BindException;   

5.  import org.springframework.web.servlet.ModelAndView;   

6.  import org.springframework.web.servlet.mvc.SimpleFormController;   

7.    

8.  import zz.it.beans.LoginForm;   

9.    

10. public class LoginController extends SimpleFormController {   

11.     /**  

12.      * 构造方法  

13.      */  

14.     public LoginController() {   

15.         // TODO Auto-generated constructor stub  

16.         //setCommandClass(LoginForm.class);   

17.         //这句话要是不写的话,那么在dd-servlet.xml中的loginController里面配置上如下:  

18.         // <property name="commandClass">   

19.         //<value>zz.it.beans.LoginForm</value>  

20.         //</property>   

21.         //这样效果也是一样的   

22.     }   

23.   

24.     public ModelAndView onSubmit(Object cmd, BindException errors) {   

25.         LoginForm loginForm = (LoginForm) cmd;   

26.         if (loginForm.getUserName().equals("test")   

27.                 && loginForm.getPassword().equals("test")) {   

28.             return new ModelAndView(getSuccessView(), "welcomeuser", loginForm   

29.                     .getUserName());   

30.         } else {   

31.             errors.reject("ccc""用户名或密码有误!");   

32.             errors.rejectValue("userName""nameErr"null"用户名错误");   

33.             errors.rejectValue("password""passErr"null"密码错误");   

34.             return new ModelAndView(getFormView(), errors.getModel());   

35.         }   

36.     }   

37. }   

38. </SPAN></SPAN>  

7.最后,整合部署,访问http://localhost:1234/MySpringMvc/login.do  

 效果图

 初始登录界面



  登录成功页面


   登录失败页面


 

我估计初学者,最关心的大都有这两个问题

 1.这个controller是怎样像struts那样进行封装数据的

 2.<spring:bind>为什么这么用,为什么取值只能是command.xxx

 

1.controller是怎样进行数据封装的

要说这个问题,我不得不说SimpleFormController

SimpleFormControllerAbstractFormController的具体实现,允许你在配置文件里通过successViewformView属性来配置成功视图(表单成功提交后要转向的页面)和表单视图(显示表单的页面);如果提交不合法(有三种可能:1.validator出错。2.bind错误,也就是说从请求中提取参数封装到command的过程中出现了类型转化错误,比如将一个含字母字符串转换为Integer3.onBindAndValidate()方法出错),则会重新返回到表单视图;如果提交合法,onSubmit()方法的默认实现会转向成功页面,当然你可以覆写该方法在转向之前填充一些你想返回的信息。

    SimpleFormController的工作流与AbstractFormController差不多,唯一的不同是你不必自己去实现showForm()processFormSubmission()showForm()这个方法已经被类SimpleFormController实现了并被限定为final,你不可以在继承SimpleFormController的子类里覆写这个类。processFormSubmission()这个方法尽管可以去覆写但由于它几乎可以满足所有的要求,因此一般也不会有人去重写它。
它的处理流程是这样的:   
get请求来到时,这样处理:   
1) 请求传递给一个controller对象   
2) 调用formBackingObject()方法,创建一个command对象的实例。  
3) 调用initBinder(),注册需要的类型转换器   
4) 调用showForm()方法,返回准备呈现给用户的视图 ,如果“bindOnNewForm”属性设为true,ServletRequestDataBinder会将初始请求参数填入一个新的表单对象,并且执行onBindOnNewForm()方法。
5) 调用referenceData()方法,准备给用户显示相关的数据。如用户登录需要选择的年度信息  
6) 返回formView指定的视图

post请求来到时,这样处理:   
1) 如果sessionForm属性没有设定,则调用formBackingObject()方法,创建一个command对象的实例。否则从session中取得表单对象  
2) 将请求传来的参数写入command对象,看它的源代码,会发现它是这样来做的:

ServletRequestDataBinder binder = createBinder(request, command);
binder.bind(request);

3)执行onBind()方法,在绑定数据之后,验证数据之前对表单数据进行一些自制的修改动作。   
4) 如果设置为要求验证(validateOnBinding属性被设定),则调用validator类进行数据验证  
5) 调用onBindAndValidate()方法,该方法允许自定义数据绑定和校验处理  
6)执行processFormSubmission()检验 Errors对象中含不含错误,如果含有错误则执行showForm()返回到填写表单页面;否则执行onSubmit()方法,进行提交表单,然后转向成功页面。

2.<spring:kind>的用法

Spring框架体系下,可以说规约最少,最不受限制的就是表现层技术了。不像Struts,改定了好多的标签,而且有些功能还和标签绑定了。Sping也定义了一些标签,但这些标签只是给使用者提供了一些方便,并不会提供额外的功能或效果。

Sping Tag比较少,不超过十个,这里只介绍最常用的一个<sping:bind>,也叫作Spring绑定

<sping:bind>path属性制定了与表单中的那个属性绑定,这样,${status.expression}就代表了那个属性的名称,${status.expression}代表那个属性的值。如果path属性为“XXX.*”则与那个表单的所有属性绑定。

上面的例子表单有两个属性usernamepassword。实际上绑定方式有两种,第一种就像我的上一篇http://javacrazyer.iteye.com/blog/790834文章讲的的那样,第二种如下:

......
  <spring:bind path="loginForm">
      用户名:
<INPUT name="userName" type="text" value="${command.userName}"/><br>
      密码:
<INPUT name="password" type="password" value="${command.password}"/>
     </spring:bind>

这样尽管也行,但在错误信息处理上,针对用户名和密码的报错信息不会像原来那样显示出来了


 

所以验证我下面要说的话:

使用<sping:bind>标签,在初次进入表单页面时并不会有什么作用,而是当表单提交后,如果有BindException错误时再返回这个页面时,可以把先前的输入显示在input里。

 

说到错误信息处理,我又要许多要说了,来看看我前一篇文章http://javacrazyer.iteye.com/blog/790834controller中的

errors.reject("ccc", "用户名或密码有误!");
   return new ModelAndView(getFormView(), errors.getModel());

它调用了BindExceptionreject方法,这样,再调用BindExceptiongetModel()方法,就把错误连同表单等信息一并返回到表单页面用以显示。

reject方法的第一个参数是错误码,如果设定了国际化资源,则显示资源文件中该错误码对应的错误条目,如果没有设定了国际化资源,则显示reject方法的第二个参数。

reject方法的不足之处是在表现层不能区分错误消息属于那个字段,即不能说明是username不对呢还是password不对。解决这种情况可以使用rejectValue方法,这也是更一般使用的方法。rejectValue方法定义如下:

rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage)


第一个参数指定表单的域,即usernamepassword,这样就可以分辨到底是那块出了问题;第二个参数和reject方法的第一个参数一样,制定错误码;第三个参选数制定了资源文件中的占位符;第四个参数和和reject方法的第二个参数一样。rejectValue方法还有一个简化的定义

rejectValue(String field, String errorCode, String defaultMessage)


上面是在Controller里使用的方法,使用上述方法后,若果出现BindException错误,返回表单页面时就会显示错误信息,那么如何在页面里显示错误信息呢?

上面/WEB-INF/jsp/login.jsp里由于在controller里使用的是reject方法,所以只能那么显示,如果我们使用rejectValue方法,例如改动LoginController

errors.rejectValue("userName", "nameErr", null, "用户名错误");
   errors.rejectValue("password", "passErr", null, "密码错误");

这样,就可以把页面改为如之前最后的形式

 <spring:bind path="command.userName">
        名称
<input type="text" name="${status.expression}" value="${status.value}"/>
            <font color="red"><c:out value="${status.errorMessage}" /></font><br/>
 </spring:bind> 
 <spring:bind path="command.password">
        密码
<input type="password" name="${status.expression}" value="${status.value}"/>
         <font color="red"><c:out value="${status.errorMessage}" /></font><br/>
   </spring:bind>

这样错误的消息就绑定到相应的字段了。当然也可以不制定某个字段,一股脑都输出

到此,大家还是没看到我是怎样讲解command这个值的,至于为什么非要是command而不是其他值
这是因为setCommandClass这个方法是AbstractController中的一个方法,而这个
方法使用到的一个默认值public static final java.lang.String DEFAULT_COMMAND_NAME = "command";public static final java.lang.String DEFAULT_COMMAND_NAME = "command";
看到了没有,就是叫做command,所以在标签中就敢大胆的用啦 

 

3.最后还有几个小问题

1)一个常见的错误:
不通过controller直接访问含有spring:bind标签的JSP页面会出现下面的错误:
javax.servlet.ServletException: Neither Errors instance nor plain target object for bean name 'person' available as request attribute
解决办法:
http://spring.jactiongroup.net/viewtopic.php?p=5482

2)星号(*)的意思
global and all field errors,
    ## use wildcard (*) in place of the property name
    <spring:bind path="company.*">
        <c:forEach items="${status.errorMessages}" var="error">
       c:out value="${error}"/><br/>
        </c:forEach>
    </spring:bind>

3command的意思
   3-1 commandClass
  
相当于struts中的ActionForm,用来封装V中的数据,方便在C中使用。

3-2 commandName
   用来指定JSP中的数据需要绑定到哪个对象。默认为
command
   比如下面的配置中,commandName就是
command
     <spring:bind path='command.email'>
     <td><input type='text' name='${status.expression}'
                value='${status.value}' size='30'
                maxlength='100'></td></tr>
     </spring:bind>
因为是缺省值,所以它就不需要再在Controller中显示声明

如果在Controller中设置了setCommandName("me");则上面的配置文件需要改为:
     <spring:bind path='me.email'>
     <td><input type='text' name='${status.expression}'
                value='${status.value}' size='30'
                maxlength='100'></td></tr>
     </spring:bind>
简单吧。


4)一个要注意的问题(原文链接)


一个普通的<spring.bind>的使用类似于:

<spring:bind path="user.age">
      <input type="text" name="age" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

需要注意的是:<input>name属性值必须与<spring:bind>path属性的匹配,否则就绑定不了!

例如下面的代码就绑定不了

<spring:bind path="user.age">
      <input type="text" name="theAge" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

为了避免手误,强烈推荐下列方法来绑定:

<spring:bind path="user.age">
      <input type="text" name="${status.expression}" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值