美文网首页
Spring MVC体系简介

Spring MVC体系简介

作者: 枯木风 | 来源:发表于2018-12-02 23:46 被阅读0次

    Spring MVC体系概述

    体系结构
    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内部逻辑

        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一旦发现上下文中有用户自定义的组件,就不会使用默认的组件。



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

    注: 标注了Spring MVC通过@Controller注解的类使其成为一个可处理Http请求的控制器(使用<context:component-scan/>扫描相应的类包),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,请求方法,请求参数及报文头的映射条件,它们之间是与的关系,联合使用多个条件项可让请求映射更加精细化。


    • "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个参数
    使用@RequestHeader绑定请求报文头的属性值
    使用命令/表单对象绑定请求参数值
    使用Servlet API对象作为入参
    使用I/O对象作为入参

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

    使用HttpMessageConverter<T>

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

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

    HttpMessageConverter<T>的实现类



        RequestMappingHandleAdapter默认已经转配了以下HttpMessageConverter:
    1. StringHttpMessageConverter
    2. ByteArrayHttpMessageConverter
    3. SourceHttpMessageConverter
    4. AllEncompassingFormHttpMessageConverter
    使用HttpMessageConverter<T>

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

    • 使用@RequestBody/@ResponseBody对处理方法进行标注
    • 使用HttpEntity<T>/ResponseEntity<T>作为处理方法的入参或返回值
    1. 使用@RequestBody/@ResponseBody

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

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

    2. 使用HttpEntity<T>/ResponseEntity<T>

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




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

        在2处的处理方法返回值类型为ResponseEntity<byte[]>,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


        控制器相应的方法如下:



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

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


    相关文章

      网友评论

          本文标题:Spring MVC体系简介

          本文链接:https://www.haomeiwen.com/subject/zfqecqtx.html