Spring MVC

来源:互联网 发布:台达触摸屏编程实例 编辑:程序博客网 时间:2024/05/11 20:09

    当前流行的mvc框架主要有struts1,webwork,struts2,spring mvc,jsf。Struts 1 是最早的mvc框架,之后出来的webwork涉及思想非常优秀但是很遗憾,没有得到太多的应用。在struts1和webwork的基础上,发展起来了struts2的框架,这是目前主要使用的框架之一,jsf是一个事件驱动的mvc框架。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。Spring mvc的功能组件划分细致、灵活和低耦合,将是mvc的发展方向。

Mvc框架都做了什么

 

  • 以controller为中心,完成对系统流程的控制管理
  • 从请求中收集数据
  • 对传入的参数进行验证
  • 根据请求调用相应的业务逻辑完成数据处理(model)
  • 将结果返回给视图
  • 针对不同的视图技术提供不同的视图解析方案,国际化支持
  • 通过拦截器链实现面向方面编程(AOP)完成系统级控制

Spring mvc的核心组件

每一个组件其实就是一组java接口,或者有框架自己实现,或者是自己实现

  1.  Dispatcher Servletservlet的分发器,总的控制中心,根据映射关系Handler Mapping分发到到自己实现的servlet
  2.  Handler Mapping(将具体的请求派发给具体的控制器)
  3.  Controller(处理自己的业务逻辑)
  4.  ViewResolve (视图解析映射,将逻辑视图映射到具体的实现类,策略)& View(视图类)
  5.  Interceptors (拦截器链)
  6.  localResolver(国际化)
  7.  Validate(验证)

 

Spring核心原理

  •  用户发送请求给服务器。urluser.do
  •  服务器收到请求。发现DispatchServlet可以处理。于是调用DispatchServlet
  •  DispatchServlet内部,通过HandleMapping查查这个url有没有对应的Controller。如果有,则调用Controller
  •  Controller开始执行
  •  Controller执行完毕后,如果返回字符串,则ViewResolver将字符串转化成相应的视图对象;如果返回 ModelAndView对象,该对象本身就包含了视图对象信息。
  •  ViewResolver 将执视图对象中的数据,输出给服务器。
  •  服务器将数据输出给客户端。

 

    简单的理解就是:

 

      Spring MVC内部相关处理逻辑:


       http请求被servlet-mapping转发到框架管理,DispatchServlet接收这个请求,并根据Handler Mapping进行映射,找到处理他的servlet也就是controllercontroller在处理这个请求的前后可能会被拦截器拦截,来完成一些其他工作,如记录日志,权限管理等等,并且spring mvc框架提供了数据验证的功能,可以在数据传入的时候进行验证。当controller处理完请求后,建立好数据模型,并返回一个逻辑视图,由view Resolvor进行视图解析,找到真正的显示视图,向用户呈现数据。

 

Demo

下面是一个完整的基于xml的springMVC的配置文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xmlns:context="http://www.springframework.org/schema/context"             xmlns:aop="http://www.springframework.org/schema/aop"             xmlns:tx="http://www.springframework.org/schema/tx"             xsi:schemaLocation="http://www.springframework.org/schema/beans                     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd                     http://www.springframework.org/schema/context                     http://www.springframework.org/schema/context/spring-context-3.0.xsd                     http://www.springframework.org/schema/aop                     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd                     http://www.springframework.org/schema/tx                     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">                      <!-- 4,Handler Mapping组件,   完成具体的请求到具体的controller的映射 -->   <!-- 当加载这个配置文件的时候,会首先实例化以HandlerMapping结尾的类,如下面的SimpleUrlHandlerMapping类,   然后在它里面查找映射关系 -->   <!-- SimpleUrlHandlerMapping是基于url的控制器 -->     <bean class = "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">     <!-- 映射属性 -->     <property name = "mappings">     <!-- 映射键值对 -->     <props>     <!-- 当请求时start.test时,将控制交由startController这个controller处理 -->     <prop key="start.test">startController</prop>     <!--  -->     <prop key="login.test">loginController</prop>          <prop key="logout.test">logoutController</prop>     <!--<prop key="addUser.test">addUserController</prop>-->     <!--  <prop key="addUserAction.test">addUserActionController1</prop>  -->     <prop key="addUserAction.test">addUserActionController2</prop>     <!-- 这里使用了一个formcontroller,这个controller很特殊-->     <!--  <prop key="addUser.test">addUserActionController3</prop>  -->     <prop key="toAdd.test">addUserActionController4</prop>     <prop key="addUserAction.test">addUserActionController4</prop>     </props>     </property>     </bean>     <!--  基于类名的handlermapping,比如请求abc.test,则mapping会自动映射到AbcController的控制器,可以简化映射的配置     <bean class = "org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>           基于beanname的映射,上面是基于class的映射     <bean class = "org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>    -->          <!-- 这个controller实现直接映射(参数化的视图控制器),也就是说只是返回一个逻辑视图名“login”(view = “login”),     然后由View Resolver解析为login.jsp。不需要实现自己的controller,spring框架自己提供了 -->     <bean id = "loginController" class = "org.springframework.web.servlet.mvc.ParameterizableViewController">     <property name="viewName" value = "login"></property>     </bean>             <!-- 这个controller是一个更加简化的controller,基于文件名的视图控制器,它直接根据请求的文件名,来返回视图的逻辑名,     逻辑名就是请求文件名,如这里如果请求logout.test,则它返回一个“logout” ,之后再经由view resolver解析为logout.jsp-->     <bean id = "logoutController" class = "org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>    <!-- 请求addUser.test,这里会直接将请求的文件名,作为逻辑视图名返回,注意这里返回的是请求的文件名,而不是这里的控制器名的前半部分 -->    <bean id = "addUserController" class = "org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>        <!-- 3,实现和注册我们的controller,controller组件 -->                 <bean id= "startController" class = "hust.StartController"></bean><!-- 使用继承自AbstractController的控制器 --><bean id = "addUserActionController1" class = "hust.AddUserActionController1"></bean><!-- 配置自定义属性编辑器,加入到一个map里面去,map的key是要转换的类型的全名称,value是我们自己写的转换器 这种方法有点问题,暂时还没有解决<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entry key="java.util.Date"><bean class="hust.MyEditor"><property name="pattern" value="yyyy-MM-dd"/></bean></entry></map></property></bean>--><!-- 使用继承自AbstractCommandController的控制器  这里还涉及了数据绑定--><bean id = "addUserActionController2" class = "hust.AddUserActionController2"><!-- 使用反射机制,自动注入时需要制定注入的类的类型 --><property name="commandClass" value = "hust.User"></property></bean><!-- SimpleFormController是AbstractFormController的具体实现,     允许你在配置文件里通过successView和formView属性来配置成功视图(表单成功提交后要转向的页面)和表单视图(显示表单的页面)      它可以处理表单流程     --><bean id = "addUserActionController3" class = "hust.AddUserActionController3"><!-- 使用反射机制,自动注入时需要制定注入的类的类型 --><property name="commandClass" value = "hust.User"></property><!-- 当第一次以get方法请求页面的时候,他不会执行onSubmit方法,但是referenceData会被执行,返回视图需要的数据,同时返回一个addUser的逻辑视图当提交表单的时候,还是会到这个controller,但是这是是以post方式提交的,所以它只会执行onSubmit方法也就是说对于同一个请求他会根据不同的请求方式,给出不同的响应方式 --><property name="formView" value = "addUser"></property><property name="successView" value = "addUserSuccess"></property></bean><bean id = "addUserActionController4" class = "hust.AddUserActionController4"><!-- 方法名解析器 --><property name="methodNameResolver"><!-- 根据请求的路劲来解析响应的方法调用 --><bean class = "org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver"></bean></property></bean><bean id = "addUserServController" class = "hust.UserController"><!-- 使用反射机制,自动注入 --><property name="commandClass" value = "hust.User"></property></bean><!-- resolve是一种策略,完成逻辑名称(字符串)到view真实视图的映射,真正的处理是由 viewclass来完成的-->    <!-- 基于url的视图解析器 ViewResolve & View 组件-->              <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">    <!-- Resolver和view 要结合使用,这里试试使用jsp作为视图层,jstl在jsp显示的时候可以完成国际化的处理-->    <!-- 在我们的例子中,viewclass 并没有做什么事情, -->    <property name="viewClass" value = "org.springframework.web.servlet.view.JstlView"></property>    <!-- 指定请求的前缀 -->    <property name="prefix" value = "/WEB-INF/jsp/"></property>    <!-- 指定请求的后缀 -->    <property name="suffix" value = ".jsp"></property>         <!-- 对于名字为“start”的逻辑视图,按照上面的配置,会进行拼装成/WEB-INF/jsp/start.jsp,     在spring框架内部会使用request.forward()方法实现跳转 -->    </bean>       </beans>

完整的代码在gitHub:https://github.com/raiet/SpringMCV/tree/master/test_spring

0 0