spring mvc控制框架的流程及原理2: 例子说明

spring mvc运行步骤:

  1. 首先用户发送请求http://localhost:8080/hello——>web容器,web容器根据“/hello”路径映射到DispatcherServlet(url-pattern为/)进行处理;
  2. DispatcherServlet——>BeanNameUrlHandlerMapping进行请求到处理的映射,BeanNameUrlHandlerMapping将“/hello”路径直接映射到名字为“/hello”的Bean进行处理,即HelloWorldController,BeanNameUrlHandlerMapping将其包装为HandlerExecutionChain(只包括HelloWorldController处理器,没有拦截器);
  3. DispatcherServlet——> SimpleControllerHandlerAdapter,SimpleControllerHandlerAdapter将HandlerExecutionChain中的处理器(HelloWorldController)适配为SimpleControllerHandlerAdapter;
  4. SimpleControllerHandlerAdapter——> HelloWorldController处理器功能处理方法的调用,SimpleControllerHandlerAdapter将会调用处理器的handleRequest方法进行功能处理,该处理方法返回一个ModelAndView给DispatcherServlet;
  5. hello(ModelAndView的逻辑视图名)——>InternalResourceViewResolver, InternalResourceViewResolver使用FreeMarkerView,具体视图页面在classpath:/templates/hello.ftl;
  6. FreeMarkerView(classpath:/templates/hello.ftl)——>渲染,将在处理器传入的模型数据(message=HelloWorld!)在视图中展示出来;
  7. 返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

到此HelloWorld就完成了,主要进行了如下配置:

  1. 前端控制器DispatcherServlet;
  2. HandlerMapping
  3. HandlerAdapter
  4. ViewResolver
  5. 处理器/页面控制器
  6. 视图

web.xml配置

<servlet>
    <servlet-name>helloworld</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:config/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>helloworld</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

load-on-startup:表示启动容器时初始化该Servlet; url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“*.html”表示拦截所有以html为扩展名的请求。 自此请求已交给Spring Web MVC框架处理,因此我们需要配置Spring的配置文件,默认DispatcherServlet会加载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件。本示例为WEB-INF/helloworld-servlet.xml。

在Spring配置文件中配置HandlerMapping、HandlerAdapter

/src/main/resources/config/spring-mvc-by-manual.xml

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       ">
    <!-- 处理器 -->
    <bean name="/hello" class="com.tom.web.controller.HelloWorldController"/>

    <!-- HandlerMapping -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

    <!-- HandlerAdapter -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
</beans>

BeanNameUrlHandlerMapping:表示将请求的URL和Bean名字映射,如URL为 “上下文/hello”,则Spring配置文件必须有一个名字为“/hello”的Bean,上下文默认忽略。 SimpleControllerHandlerAdapter:表示所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为Spring Web MVC中的处理器。如果需要其他类型的处理器可以通过实现HadlerAdapter来解决。

在Spring配置文件中配置ViewResolver

支持JSP

<!-- 定义视图解析器 -->
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="classpath:/templates/"></property>
    <property name="suffix" value=".jsp"></property>
    <property name="order" value="1"/>
</bean>
  • InternalResourceViewResolver:用于支持Servlet、JSP视图解析;
  • viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl的相关jar包;
  • prefix和suffix:查找视图页面的前缀和后缀(前缀[逻辑视图名]后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在“classpath:/templates/hello.jsp”;

支持Freemarker

<!-- 配置freeMarker的模板路径 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="classpath:/templates/" />
    <property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- freemarker视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <property name="suffix" value=".ftl" />
    <property name="order" value="0"/>
    <property name="contentType" value="text/html;charset=UTF-8" />
    <!-- 此变量值为pageContext.request, 页面使用方法:rc.contextPath -->
    <property name="requestContextAttribute" value="rc" />
</bean>

order决定视图的优先级,本例中首先查找classpath:/templates/xxx.ftl再试着找classpath:/templates/xxx.jsp

支持返回json

配置方法1

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.12</version>
</dependency>
<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <!-- 配置Fastjson支持 -->
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>application/json</value>
                </list>
            </property>
            <property name="features">
                <list>
                    <value>WriteMapNullValue</value>
                    <value>QuoteFieldNames</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

配置方法2

仅有以下配置有乱码

 <mvc:view-resolvers>
        <mvc:content-negotiation>
            <mvc:default-views>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                    <property name="jsonpParameterNames">
                        <set>
                            <value>jsonp</value>
                            <value>callback</value>
                        </set>
                    </property>
                </bean>
            </mvc:default-views>
        </mvc:content-negotiation>
        <mvc:freemarker cache-views="false"  suffix=".ftl"/>
    </mvc:view-resolvers>

必须加上

<filter>
<filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
    <param-name>encoding</param-name>
    <param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

配置方法3,@RestController注解,自动转化json对象

@RestController
public class MessageController {
    Logger logger = LoggerFactory.getLogger(MessageController.class);
    @RequestMapping(value = "/message", method = RequestMethod.POST)
    public @ResponseBody JSONObject message(@RequestParam String message) {
        logger.debug("{}", message);
        JSONObject item = new JSONObject();
        item.put("name", "我是tomLuo");
        return item;
    }
}

配置方法4,produces="application/json"

@Controller
public class MessageController {
    Logger logger = LoggerFactory.getLogger(MessageController.class);

    @RequestMapping(value = "/message", method = RequestMethod.POST,produces="application/json") (1)
    public @ResponseBody JSONObject message(@RequestParam String message) {
        logger.debug("{}", message);
        JSONObject item = new JSONObject();
        item.put("name", "我是tomLuo");
        return item;
    }
}
  1. 见下面 Spring3.1新特性 === 开发处理器/页面控制器

/src/main/java/com/tom/web/controller/HelloWorldController.java

package com.tom.web.controller; /**
 * Created by tom on 2016/5/24.
 */

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        //1、收集参数、验证参数
        //2、绑定参数到命令对象
        //3、将命令对象传入业务对象进行业务处理
        //4、选择下一个页面
        ModelAndView mv = new ModelAndView();
        //添加模型数据 可以是任意的POJO对象
        mv.addObject("message", "Hello World!");
        mv.addObject("message2", "我是tomLuo!");
        //设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
        mv.setViewName("hello");
        return mv;
    }
}
  • org.springframework.web.servlet.mvc.Controller:页面控制器/处理器必须实现Controller接口,注意别选错了;后边我们会学习其他的处理器实现方式;
  • public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) :功能处理方法,实现相应的功能处理,比如收集参数、验证参数、绑定参数到命令对象、将命令对象传入业务对象进行业务处理、最后返回ModelAndView对象;
  • ModelAndView:包含了视图要实现的模型数据和逻辑视图名;“mv.addObject("message", "Hello World!");
  • "Hello World!"表示添加模型数据,此处可以是任意POJO对象;“mv.setViewName("hello");”表示设置逻辑视图名为“hello”,视图解析器会将其解析为具体的视图,如前边的视图解析器InternalResourceVi。wResolver会将其解析为“classpath:/templates/hello.ftl”。
  • name="/hello":前边配置的BeanNameUrlHandlerMapping,表示如过请求的URL为 “上下文/hello”,则将会交给该Bean进行处理。

> 以上Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类

注解式处理器支持

Spring2.5: 注解式处理器

Spring2.5引入注解式处理器支持,通过@Controller 和 @RequestMapping注解定义我们的处理器类

需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller 和 @RequestMapping注解的处理器。

  • @Controller:用于标识是处理器类;
  • @RequestMapping:请求到处理器功能方法的映射规则;
  • @RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
  • @ModelAttribute:请求参数到命令对象的绑定;
  • @SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
  • @InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;

开启注解

<context:component-scan base-package="com.tom.web.controller" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 开启注解 -->
<mvc:annotation-driven/>

只扫描com.tom.web.controller.*, 仅有@Controller的处理类

Spring3.0: RESTful架构风格支持

Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),且又引入了更多的注解支持:

  • @CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定;
  • @RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
  • @RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
  • @ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
  • @ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因;
  • @ExceptionHandler:注解式声明异常处理器;
  • @PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格

其它支持

  • JSR-303验证框架的无缝支持(通过@Valid注解定义验证元数据);
  • 使用Spring 3开始的ConversionService进行类型转换(PropertyEditor依然有效),支持使用@NumberFormat 和 @DateTimeFormat来进行数字和日期的格式化;
  • HttpMessageConverter(Http输入/输出转换器,比如JSON、XML等的数据输出转换器);
  • ContentNegotiatingViewResolver,内容协商视图解析器,它还是视图解析器,只是它支持根据请求信息将同一模型数据以不同的视图方式展示(如json、xml、html等),RESTful架构风格中很重要的概念(同一资源,多种表现形式);
    Spring 3 引入 一个  mvc XML的命名空间用于支持mvc配置,包括如:
      * <mvc:annotation-driven>:
      自动注册基于注解风格的处理器需要的DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter
      支持Spring3的ConversionService自动注册
      支持JSR-303验证框架的自动探测并注册(只需把JSR-303实现放置到classpath)
      自动注册相应的HttpMessageConverter(用于支持@RequestBody  和 @ResponseBody)(如XML输入输出转换器(只需将JAXP实现放置到classpath)、JSON输入输出转换器(只需将Jackson实现放置到classpath))等。
    * <mvc:interceptors>:注册自定义的处理器拦截器;
    * <mvc:view-controller>:和ParameterizableViewController类似,收到相应请求后直接选择相应的视图;
    * <mvc:resources>:逻辑静态资源路径到物理静态资源路径的支持;
    * <mvc:default-servlet-handler>:当在web.xml 中DispatcherServlet使用<url-pattern>/</url-pattern> 映射时,能映射静态资源(当Spring Web MVC框架没有处理请求对应的控制器时(如一些静态资源),转交给默认的Servlet来响应静态文件,否则报404找不到资源错误,)。

Spring3.1新特性:

  • 对Servlet 3.0的全面支持。
  • @EnableWebMvc:用于在基于Java类定义Bean配置中开启MVC支持,和XML中的<mvc:annotation-driven>功能一样;
  • 新的@Contoller和@RequestMapping注解支持类:处理器映射RequestMappingHandlerMapping 和 处理器适配器RequestMappingHandlerAdapter组合来代替Spring2.5开始的处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter。
  • 新的@ExceptionHandler 注解支持类:ExceptionHandlerExceptionResolver来代替Spring3.0的AnnotationMethodHandlerExceptionResolver。
  • @RequestMapping的"consumes" 和 "produces" 条件支持:用于支持@RequestBody 和 @ResponseBody,
    1. consumes指定请求的内容是什么类型的内容,即本处理方法消费什么类型的数据,如consumes="application/json"表示JSON类型的内容,Spring会根据相应的HttpMessageConverter进行请求内容区数据到@RequestBody注解的命令对象的转换;
    2. produces指定生产什么类型的内容,如produces="application/json"表示JSON类型的内容,Spring的根据相应的HttpMessageConverter进行请求内容区数据到@RequestBody注解的命令对象的转换,Spring会根据相应的HttpMessageConverter进行模型数据(返回值)到JSON响应内容的转换
  • URI模板变量增强:URI模板变量可以直接绑定到@ModelAttribute指定的命令对象、@PathVariable方法参数在视图渲染之前被合并到模型数据中(除JSON序列化、XML混搭场景下)。
  • @Validated:JSR-303的javax.validation.Valid一种变体(非JSR-303规范定义的,而是Spring自定义的),用于提供对Spring的验证器(org.springframework.validation.Validator)支持,需要hibernate Validator 4.2及更高版本支持;
  • @RequestPart:提供对“multipart/form-data”请求的全面支持,支持Servlet 3.0文件上传(javax.servlet.http.Part)、支持内容的HttpMessageConverter(即根据请求头的Content-Type,来判断内容区数据是什么类型,如JSON、XML,能自动转换为命令对象),比@RequestParam更强大(只能对请求参数数据绑定,key-alue格式),而@RequestPart支持如JSON、XML内容区数据的绑定;
  • Flash 属性 和 RedirectAttribute:通过FlashMap存储一个请求的输出,当进入另一个请求时作为该请求的输入,典型场景如重定向 POST-REDIRECT-GET模式,
    1. POST时将下一次需要的数据放在FlashMap;
    2. 重定向;
    3. 通过GET访问重定向的地址,此时FlashMap会把1放到FlashMap的数据取出放到请求中,并从FlashMap中删除;从而支持在两次请求之间保存数据并防止了重复表单提交)。
  • Spring Web MVC提供FlashMapManager用于管理FlashMap,默认使用SessionFlashMapManager,即数据默认存储在session中。

参考阅读:

源码阅读:

https://github.com/tomlxq/best-practice/tree/master/springmvc-helloworld

时间: 2024-08-09 02:00:44

spring mvc控制框架的流程及原理2: 例子说明的相关文章

spring mvc控制框架的流程及原理1: 总概及源码分析

主要介绍spring mvc控制框架的流程及原理 Spring Web MVC处理请求的流程 具体执行步骤如下: 首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分:图2-1中的1.2步骤: 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理:处理完毕后返回一个Model

[读后感]spring Mvc 教程框架实例以及系统演示下载

太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 不要好意思,昨晚写的,睡着忘发了,后附是篇好文,赶紧w分享一下. 感脚着,俺好像做了件聪明事儿,却不知会不会遭到不理解. 转载的好文,是不会推荐到

搭建基于全注解的Spring+Spring MVC+Hibernate框架

以实例讲解Spring+Spring MVC+Hibernate框架搭建步骤: 一.配置web.xml Xml代码   <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XML

Spring+Spring MVC+Hibernate框架搭建实例

前言:这里只是说明整个搭建流程,并不进行原理性的讲解 一 下面所需要用到的数据库配置: 数据库方面,使用mysql创建一个users表,具体代码如下: DROP TABLE IF EXISTS `users`; CREATE TABLE `users` (   `UserID` int(4) NOT NULL AUTO_INCREMENT,   `UserName` varchar(16) NOT NULL,   `Password` varchar(16) NOT NULL,   `Telep

Spring MVC Web框架

1. Spring MVC简介 Spring MVC是java EE平台请求驱动类型的轻量级Web框架,使用了MVC设计模式的思想,spring框架的主要优势之一就是分层架构,分层架构允许选择使用任何一个组件,同时也可以集成其它框架技术,例如:Struts2.Hibernate等 Spring框架具有以下特点: 1. 方便解耦,简化开发.通过spring3提供的IoC容器,可以将对象之间的依赖关系交由Spring3控制,避免编码所造成的程序过度耦合 2. AOP编程的支持.通过Spring3提供

Spring MVC 学习总结(六)——Spring+Spring MVC+MyBatis框架集成

目录 一.新建一个基于Maven的Web项目    二.创建数据库与表    三.添加依赖包    四.新建POJO实体层    五.新建MyBatis SQL映射层    六.JUnit测试数据访问    七.完成Spring整合MyBatis配置    八.配置web.xml加载Spring容器与MVC    九.创建服务层     十.完成商品管理功能    10.1.商品列表与分页    11.2.删除与多删除功能    11.3.新增商品功能    11.4.编辑商品功能    11.

Spring MVC的框架组件

DispatcherServlet:前端控制器用户请求到达前端控制器,它相当于MVC中的C,dispatcherServlet没有处理业务的能力,它是整个流程的控制中心,由它调用其他组件处理用户的请求,它的存在是为了降低其他组件之间的耦合性. HandlerMapping:处理器映射器负责根据用户请求找到Handler(处理器),Spring MVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,注解方式,实现接口方式. Handler:处理器(我们一般后台写的程序用@RestCont

轻量级 Spring Mvc Api框架

相信大家开发web项目时和别人合作接口联调并不陌生,写完接口了解接口有很多种沟通方法,写wiki,看源代码,写文档等等,当然还有一些比较出名的文档框架如swagger,但是我对swagger的框架并不满意,首先他的引入不够轻量级,其次他对代理bean的支持非常差.于是我自己开发了一套轻量级spring Mvc Api

Spring MVC控制层的返回类型--String类型与Bean类型

SpringMVC控制层的返回类型形式多样,现拿其中的两种--String类型与Bean类型作以说明. 一.测试项目的结构 说明:(jsp的名字没起好) 控制层:UserController.java --对用户的相关操作: 视图层:toFormTest.jsp--跳转至formTest.jsp (这样跳转的原因:1.由于jsp文件夹在WEB-INF目录下,所以无法直接访问:2.在目标地址formTest.jsp中的表单采用了sf标签,需在控制层中初始化表单所绑定的bean对象,所以需先进入控制