Spring MVC

本文详细介绍了Spring MVC框架的主要功能组件、核心原理及配置示例,包括控制器、视图解析、国际化支持等关键部分。通过具体XML配置文件展示了如何实现基于XML的Spring MVC应用,为开发者提供了一套全面的实践指南。

    当前流行的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值