Spring MVC体系简介

Spring MVC体系概述

体系结构
Spring MVC体系简介_第1张图片
  1. 客户端发出一个Http请求,web应用服务器接收到这个请求。如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),则web容器将该请求转交给DispatcherServlet处理。

  2. DispatcherSerovlet接收到这个请求后,将根据请求的信息(包括URL,HTTP方法,请求报文头,请求参数,Cokie等)及HandlerMapping的配置找到处理请求的处理器(Handler)。可将HandlerMapping看作路由控制器,将Handler看做目标主机。值得注意的是,在SpringMVC中并没有定义一个Handler接口,实际上,任何一个Object都可以作为请求处理器。

  3. 当DispatcherServlet根据HandlerMapping得到对应当前请求的Handler后,通过HandlerAdapter对handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter是SpringMVC的框架级接口,顾名思义,HandlerAdapter是一个适配器,它用统一的接口对各种Handler方法进行调用

  4. 处理器完成业务逻辑的处理之后将返回一个ModelAndView给DispatcherServlet,ModelAndView包含了视图逻辑名和模型数据信息。

  5. ModelAndView包含的是“视图逻辑名”而非真正的视图对象,DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作。

  6. 得到真实的视图对象View后,DispatcherServlet就使用这个View对象对ModelAndView中的模型数据进行视图渲染。

  7. 最终客户端得到的响应消息可能是一个普通的HTML页面,也可能是一个XML或JSON串,甚至是一张图片或一个PDF文档等不同媒体形式。

DispatcherServlet内部逻辑
Spring MVC体系简介_第2张图片

    initStrategies()方法将在WebApplicationContext初始化后自动执行,此时Spring上下文中的Bean已经初始化完毕。该方法的工作原理是:通过反射机制查找并装配Spring容器中用户显示自定义的组件Bean,如果找不到,则装配默认的组件实例。

    Spring MVC定义了一套默认的组件实现类,也就是说,即使在Spring容器中没有显示定义组件bean,DispatcherServlet也会装配好一套可用的默认组件。在Spring-webmvc-4.x.jar包的org/springframework/web/servlet类路径下拥有一个DispatcherServlet.propertiesp配置文件,该文件指定了DispatcherServlet所使用的默认组件。

    如果希望采用非默认的组件,则只需要在Spring配置文件中配置自定义的组件Bean即可。Spring MVC一旦发现上下文中有用户自定义的组件,就不会使用默认的组件。

Spring MVC体系简介_第3张图片

Spring MVC体系简介_第4张图片

    有些组件最多允许存在一个实例,如MutlipartResolver,LocaleResolver等;而另一些组件允许存在多个实例,如HandlerMapping,HandlerAdapter等。同一类型的组件如果存在多个,可通过order属性确定优先级迅速,值越小优先级越高。

注: 标注了Spring MVC通过@Controller注解的类使其成为一个可处理Http请求的控制器(使用扫描相应的类包),DispatcherServlet使用DefaultAnnotationHandlerMapping查找负责处理对应请求的处理器。

注解驱动的控制器

使用@RequestMapping映射请求

    @RequestMapping使用value指定请求URL,在类定义处指定的URL相对于Web应用的部署路径,而在方法定义处指定的URL则相对于类定义处指定的URL。

    @RequestMapping不但支持标准的URL,还支持Ant风格(?、*和**字符)和带{XXX}占位符的URL。例如:

  • /user/*/create,匹配/user/aa/create,/user/bb/create
  • /user/**/create,匹配/user/create,/user/aa/create,/user/aa/bb/create
  • /user/create?,匹配/user/createaa,/user/createbb
  • /user/{userId},匹配/user/123,/user/456
  • /company/{companyId}/user/{userId}/detail,匹配/company/123/user/456/detail

    通过@PathVariable可以将URL中的占位符参数绑定到控制器方法入参中。如@PathVariable("userId")。

通过请求参数,请求方法或请求头进行映射

    @RequestMapping的value,method,params及headersf分别表示请求URL,请求方法,请求参数及报文头的映射条件,它们之间是与的关系,联合使用多个条件项可让请求映射更加精细化。


Spring MVC体系简介_第5张图片
  • "params1": 表示请求必须包含名为params1的请求参数
  • "!params1": 表示请求不能包含名为params1的请求参数
  • "params1!=value1": 表示请求必须包含名为params1的请求参数,但其值不能为value1
  • {"params1=value1","param2"}: 表示请求必须包含名为params1和params2的两个请求参数,且params1必须为value1
请求处理方法签名
方法入参使用@RequestParam注解指定对应的请求参数,包含3个参数
  • value: 参数名
  • required: 是否必需,默认为true,不存在将抛出异常
  • defaultValue: 默认参数名,设置该参数时,自动将required设为false
使用@CookieValue可让处理方法入参绑定某个cookie的值,它和@RequestParam一样有3个参数
Spring MVC体系简介_第6张图片
使用@RequestHeader绑定请求报文头的属性值
使用命令/表单对象绑定请求参数值
使用Servlet API对象作为入参
Spring MVC体系简介_第7张图片
使用I/O对象作为入参

    Servlet的ServletRequest拥有getInputStream()和getReader()方法,可以通过它们读取请求的信息。相应的,ServletResponse拥有getOutputStream()和getReader()方法,可以通过它们输出响应信息。

使用HttpMessageConverter

    HttpMessageConverter是Spring的一个重要的接口,它负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息。

    DispatcherServlet默认已经安装了RequestMappingHandleAdapter作为HandleAdapter的组件实现类,HttpMessageConverter即由RequestMappingHandleAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。

HttpMessageConverter的实现类

Spring MVC体系简介_第8张图片

Spring MVC体系简介_第9张图片

Spring MVC体系简介_第10张图片

    RequestMappingHandleAdapter默认已经转配了以下HttpMessageConverter:

  1. StringHttpMessageConverter
  2. ByteArrayHttpMessageConverter
  3. SourceHttpMessageConverter
  4. AllEncompassingFormHttpMessageConverter
使用HttpMessageConverter

    SpringMVC提供了两种途径使用HttpMessageConverter将请求信息转换并绑定到处理方法的入参中:

  • 使用@RequestBody/@ResponseBody对处理方法进行标注
  • 使用HttpEntity/ResponseEntity作为处理方法的入参或返回值
1. 使用@RequestBody/@ResponseBody
Spring MVC体系简介_第11张图片

    在1处,SpringMVC将根据requestBody的类型查找匹配的HttpMessageConverter,由于StringHttpMessageConverter的泛型类型对应String,所以StringHttpMessageConverter将被SpringMVC选中,用它将请求体信息进行转换并将结果绑定到requestBody入参上。

    在2处,由于方法返回值类型为byte[],所以SpringMVC根据类型匹配的查找规则将使用ByteArrayHttpMessageConverter对返回值进行处理,即将图片数据流输出到客户端。

2. 使用HttpEntity/ResponseEntity

    和@RequestBody/@ResponseBody类似,HttpEntity不但可以访问请求和响应报文体的数据,还可以访问请求和响应报文头的数据。SpringMVC根据HttpEntity的泛型类型查找对应的HttpMessageConverter。


Spring MVC体系简介_第12张图片

Spring MVC体系简介_第13张图片

    在1处使用HttpEntity指定入参的类型,SpringMVC分析出泛型类型为String,使用StringHttpMessageConverter将请求体类型绑定到httpEntity中,返回String类型的值座位逻辑视图名。

    在2处的处理方法返回值类型为ResponseEntity,SpringMVC分析出泛型类型为byte[],使用ByteArrayHttpMessageConverter输出图片数据流。

处理XML和JSON

    SpringMVC提供了几个处理XML和JSON格式的请求/响应消息的HttpMessageConverter。

  • MarshallingHttpMessageConverter:处理XML格式的请求或响应消息
  • Jaxb2RootElementHttpMessageConverter:同上,底层使用Jaxb
  • MappingJackson2HttpMessageConverter:处理JSON格式的请求或响应消息

    因此,只要在SpringMVC容器中为RequestMappingHandlerAdapter装配好相应的处理XML和JSON格式的请求/响应消息的HttpMessageConverter,并在交互中通过请求的Accept指定MIME类型,SpringMVC就可使服务端的处理方法和客户端透明的通过XML和JSON格式的消息进行通信。

    首先为RequestMappingHandleAdapter装配可处理XML和JSON格式的请求/响应消息的HttpMessageConverter

Spring MVC体系简介_第14张图片

    控制器相应的方法如下:

Spring MVC体系简介_第15张图片

Spring MVC体系简介_第16张图片

    通过以上HTTP请求/响应报文,客户端的User对象被流化为一段对象的XML报文,同时通过报文头属性Accept和Content-Type指定接收的MIME类型和本请求的报文内容均为application/xml。

    将请求报文头属性Accept和Content-Type更改为application/json,User对象的数据以JSON格式进行传递。


Spring MVC体系简介_第17张图片

你可能感兴趣的:(Spring MVC体系简介)