Spring MVC 介绍(二)

Spring MVC 介绍(二)

Spring MVC 控制器

SpirngMVC 官方将控制器分为了前端控制器(Front Controller) 和Controller。Front Controller其实就是DispatcherServlet,只所以称它为Front Controller是因为DispatcherServlet是整个应用的入口,所有的请求都会经过这个Servlet,而这个Servlet是SpringMVC框架为我们定义好的,整个框架的启动都由它来完成,处于最前端,所以称它为Front Controller。而Controller则是我们自己定义的类,前端控制器根据配置,将请求可以“路由”到我们自己定义的控制器中的方法上。所以不管是Front Controller还是自己定义的Controller类,都还是属于MVC中的C的范畴。

  • DispatcherServlet

在DispatcherServlet的父类FrameworkServlet中定义了一个属性contextConfigLocation,它保存了SpringMVC的配置文件的位置,它的值可以在web.xml 的Servlet配置中通过初始化参数init-param来配置。所以我们通过Servlet的init-param这个配置参数来改变Spring上下文的配置路径。配置如下:

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-mvc.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
	<!-- 默认servlet映射 -->
	<url-pattern>/</url-pattern>
</servlet-mapping>
  • HandlerMapping与HandlerAdapter

DispatcherServlet作为前端控制器接收到请求之后,是如何找到我们自己写的Controller Bean,并且执行其中的方法的呢?

在SpringMVC中还有两个很重要的组件:HandlerMapping 与HandlerAdapter. HandlerMapping 称为处理器映射器,HandlerAdapter称为处理器适配器。HandlerMapping 完成的工作是辅助在SpringContext中找到我们自己写的Controller Bean,而HandlerAdapter则是适配到要调用的Controller中的方法。这两个类完成的工作一般不需要我们干预,了解它们的工作原理有助于我们灵活的使用SpringMVC框架。

1.HandlerMapping

DispatcherServlet在web容器中初始化的时候,会调用initHandlerMappings()方法来完成HandlerMapping组件的初始化工作,但是这个初始化工作一定是在Spring容器 WebApplicationContext 创建之后,因为SpringMVC中所有的组件对象都必须被Spring容器管理。

在HandlerMapping中保存了请求路径,请求方式与Controller类中方法的映射关系。DispatcherServlet在初始化的过程中创建了Spring WebApplicationContext容器,之后做的事情就是创建RequestMappingHandlerMapping 实例,扫描所有Controller类,将映射的“路由”信息保存到实例中。

2.HandlerAdapter

当客户端发起请求后,DispatcherServlet就会将请求交给HandlerMapping实例,HandlerMapping根据请求的地址和方式找到具体要执行的Controller类中的方法,最终这个方法的调用还需要交给HalderAdapter来完成。因为在HalderAdapter正式调用Controller类中的方法之前还有一些事情需要处理,比如说数据类型的转换,Controller类中方法参数的准备,上面例子中home方法有一个Model参数,在调用方法之前需要准备好Model 对象,然后在正式调用方法的时候传入。

与HandlerMapping一样,在解析mvc:annotation-driven/的时候,会创建HalderAdapter的实例,具体的类型为RequestMappingHandlerAdapter,它实现了HalderAdapter接口,在bean中还注册了一些参数解析器,类型转换器,返回值解析器等对象。

处理器适配工作完成后,Controller类中的处理器方法才开始被调用运行。

  • Controller

这里的Controller就是我们自己定义的类,这个类就是一个普通的java类,它之所以能够成为Controller,是因为我们在这个类上添加了@Controller 这个annotation, 这样Spring MVC框架就把它当做是一个Controller了。

  1. @Controller

Spring 配置中指定了自动扫描的basepackage后,Spring会扫描这些包以及子包中的使用了@Controller标识的类,然后将类加入到Spring IOC容器中,注入依赖。需要注意的是这个bean在spring IOC容器中是单例的,每次请求到来的时候,使用的是同一个bean对象。既然是单例的,那么我们在编码的时候一定要注意这个特性,在这个类中定义 field的时候,要特别注意,这个field会被所有的请求共享,所以要特别注意。

2.@RequestMapping

在Controller类中定义的方法可以用来处理请求,在SpringMVC中它叫做处理器方法(HandlerMethod),它之所以能够成为一个HandlerMethod,是因为我们在这个方法上面添加了一些annotation,正式因为这些annotation,RequestMappingHandlerMapping才能扫描到它,才能被HalderAdapter适配到,然后被框架调用。

返回值处理器

处理器方法收集到提交的数据之后,调用业务组件完成业务,然后将结果保存到Model中,处理器方法返回结果,SpringMVC需要对处理器方法的结果进行处理,那么处理器的返回值都支持哪些数据类型?框架是如何来解析这些返回的数据,然后调用视图解析器渲染成视图的?

返回值处理器HandlerMethodReturnValueHandler, 它是一个接口,SpringMVC中对这个接口有多种实现。

  • 返回值类型

SpringMVC中处理器方法支持的返回值类型有,ModelAndView,Model,Map,View,String,void .不管是那种返回类型,HandlerMethodReturnValueHandler都会统一处理后交给视图解析器来解析。对于开发人员来说,只需要把注意力集中在两点上即可,第一是Model对象,第二是View对象。

  1. ModelAndView :即包含了Model对象,也包含了视图对象,
  2. Model: 可以直接返回org.springframework.ui.Model 对象
  3. Map: 普通的Map集合对象,它会作为Model数据。
  4. View: 表示视图对象。
  5. String与void:返回String是我们使用的最多的,表示视图的逻辑名称,如果返回的是void,并不代表不需要视图,HandlerMethodReturnValueHandler会与认为没有指定逻辑名称,而默认使用请求URI作为视图名称。
  • @ResponseBody与 @RestController

使用@ResponseBody这个annotation可以返回Json视图,使用起来更简洁方便。在现代web应用发开中,服务端往往需要为不同的客户端提供服务,比如移动端的开发需要为移动端提供数据服务,返回的是数据而不应该是渲染好的HTML代码,而JSON数据格式在现代开发中被大量的使用,因为这种数据格式与程序语言无关,能够被大多数程序语言解析。

HandlerMethodReturnValueHandler在在处理返回值的时候,如果发现处理器方法上被@ResponseBody标注,就会将方法的返回值作为Response Body直接输出到客户端,而不会渲染视图。默认就是将返回值对象序列化成Json格式,内部用到的就是MappingJackson2JsonView 对象,所以在使用@ResponseBody之前先确保在maven中加入jackson-databind 依赖包。

Spring从4.0开始,为了简化开发,增加了@RestController,它的作用就相当于替换@Controller与@ResponseBody两个annotation

  • RedirectAttributes

在处理器方法中做重定向的时候,往往需要携带一些数据到下一次请求中,如果将这些携带的数据放在Model中,而Model对象在每次请求的时候都会创建,它实际上是只在Reqeust范围内有效的,重定向就是重新发起请求,所以Model会重新创建,这样数据是无法携带到下一个页面的。

odel中,而Model对象在每次请求的时候都会创建,它实际上是只在Reqeust范围内有效的,重定向就是重新发起请求,所以Model会重新创建,这样数据是无法携带到下一个页面的。

SpringMVC中提供了RedirectAttributes对象,将数据存放在这个对象中,即使在重定向的情况下,数据也能携带过去。它提供了一个addFlashAttribute方法来存放数据,之所以叫做FlashAttribute,是因为存放的该数据只要被取出一次,就会被删除掉,相当于”闪”了一下。其内部的原理其实就是把数据放到Session中,用的时候从session中取出,然后再删除掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值