1. Spring MVC通常的执行流程是:当一个Web请求被发送给Spring MVC Application,Dispatcher Servlet接收到这个请求,通过HandlerMapping找到Controller,将这个请求委派给Controller的某个Handler Method处理,这个Handler Method处理完这个请求,返回一个ModelAndView给Dispatcher Servlet,Dispatcher Servlet利用View Name,请求View Resolver,View Resolver返回相应的view;Dispatcher Servlet拿到View后,将Model传递给View,然后将Response返回;
  2. 对于每一个Controller里面的Handler Method,它可以接收以下的参数:
    • HttpServletRequest或HttpServletResponse类型的对象;
    • 任意类型的请求参数,使用@RequestParam标注,这些请求参数的值来自于Url中的request parameter;
    • 任意类型的Path Variable,使用@PathVariable来标注,这些参数的值来自于请求Path中的一部分,在使用这个的前提是你必须在这个Handler Method标注的@RequestMapping里面使用占位符;
    • Model类型的对象;你可以向这个对象里面添加attributes;
    • 任意类型的Cookie属性值,使用@CookieValue标注;
    • Map或者ModelMap类型的对象,Handler Method可以用来向Model里面添加属性;
    • Errors或者BindingResult类型的对象,Handler Method用来访问Model对象的验证结果;
    • SessionStatus类型的对象,Handler Method可以用来设置一个Session的完成;

    Handler Method可以有两种类型的返回值:

    • 一种是String,表示视图名;
    • 另外一种是void,这要取决于Handler Method接收的参数,如果其接收了ModelAndView类型的参数,并在这个参数中设置了视图名,那么这个视图名将被以后的View Resolver所使用,否则Spring会根据在@RequestMapping中配置的URL,将URL最后那部分默认的视图名,如果@RequestMapping中配置的URL最后那部分是一个通配符(*),则会将当前Handler Method的方法名作为View Name;
  3. 在一个基于SpringMVC的Web应用程序里面,一般有两种配置文件:
    • 一个是Web Application的配置文件(web.xml),你需要在里面指定一个或者多个servlet实例以及url到servlet的映射关系:

      <servlet>
      <servlet-name>servlet name</servlet-name>
      <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
      <servlet-name>servlet name</servlet-name>
      <url-pattern>/</url-pattern>
      </servlet-mapping>

      在比较大的应用程序里,指定多个DispatcherServlet实例尤其重要,这样可以让每个DispatcherServlet服务于不同的功能,拥有不同的并完全隔离的Spring Container;

    • 另外一个是Spring MVC配置文件,在没指定的情况下,每一个DispatcherServlet都会去WEB-INF目录下加载一个名为{servlet name}-servlet.xml的Spring配置文件;你也可以通过一个名为contextConfigLocation的servlet parameter来指定;
      你还可以指定一个Root Application的配置文件,这个配置文件中的bean会被每一个DispatcherServlet的配置文件中的bean访问或者复写,这个配置文件必须通过一个ContextLoaderListener类型的Listener来加载,你可以通过一个名为contextConfigLocation的context parameter来指定这个配置文件名,默认情况下这个文件是/WEB-INF/applicationContext.xml。
  4. 在你在创建Web Application的Controller之前,你需要在Application Context配置文件中添加<context:component-scan base-package="…" />去Scan所有的标记有@Controller和@RequestMapping annotations的类;或者在你的配置类上加上@ComponentScan annotation,并设置basePackages属性;
    除此之外,我们需要让Spring MVC能预注册一些Bean,所以我们需要在Application Context配置文件中加上<mvc:annotation-driven />;你也可以在你的配置类上加上@EnableWebMvc annotation达到相同的效果;
  5. 在Handler Method返回视图名之后,你需要在Application Context配置文件中添加一个ViewResolver的Bean,这个Bean负责将一个View name解析为一个View的实现;
  6. 如果我们要将一个请求映射到Controller中的一个方法,我们必须要将这个方法用@RequestMapping annotation来标注,并在这个annotation中指定映射的路径,这个路径可以是一个明确的路径,也可以包含通配符,也可以包含一些Path Variable的占位符;如果在@RequestMapping annotation中没有指定路径,则默认这个Handler Method将使用其所在Controller上配置的@RequestMapping annotation中指定的路径,你也可以在@RequestMapping中限定Request Type;
  7. Servlet API提供了Servlet Filter在Servlet被执行之前或者执行之后去拦截Web请求,Spring MVC也提供了名为Handler interceptor的组件,它用来在一个请求被Handler Method处理之前或者之后,或者在视图已经被渲染之后去拦截这个请求;Handler interceptor相对于Servlet Filter来说,它被配置在Application Context里面,所以它能利用很多Spring Container的特征,比如说可以用来引用Spring Container中的bean;为了定义一个Handler interceptor,我们要么是实现HandlerInterceptor接口,要么是继承HandlerInterceptorAdapter类;它包含3个Method:

    • preHandle()这个方法用于在Handler Method被执行之前被调用,一般返回true,否则DispatcherServlet会认为这个方法已经处理了这个请求,可以立刻将Response返回给用户;
    • postHandler()方法用于在Handler Method被执行之后被调用,在这个方法里面我们能够访问或者修改在Handler Method中生成的ModelAndView;
    • afterCompletion()方法用于在整个请求流程完成之后被调用;

    为了注册一个Interceptor到Spring Container中,我们要做一些特殊的操作:

    • 首先,我们需要将这个自定义的Handler interceptor在配置类中定义为一个bean;
    • 让配置类继承自WebMvcConfigurerAdapter类,并复写addInterceptors方法,该方法包含一个InterceptorRegistry类型的参数;
    • 调用InterceptorRegistry.addInterceptor()方法传入Handler interceptor Bean;

    默认情况下Handler Interceptor会应用到所有@Controller中的所有Handler Methods,我们也可以在addInterceptor()方法后调用addPathPatterns()去指明这个Handler Interceptor应该用到哪些URL,当然我们也可以调用excludePathPatterns()方法用于指明哪些URLs它不应该用到;

  8. 为了让Web Application支持本地化,我们需要在Spring Container中添加一个实现了LocalResolver的Bean,该Bean的name必须是localResolver;这个LocalResolver通过检测客户端提供的某些信息获取客户端Locale信息,然后设置当前请求的Locale;Spring默认提供了以下几种LocalResolver:
    • AcceptHeaderLocaleResolver:该Resolver通过读取Http Request中的accept-language header信息来获取客户端Locale信息;
    • SessionLocaleResolver:从Session中读取一个预定义的属性值,如果这个属性不存在,则从Http Request中的accept-language header中读取;你也可以通过SessionLocaleResolver的DefaultLocale属性来设置一个默认值;
    • CookieLocaleResolver:从用户浏览器的Cookie中读取一个属性值,如果这个属性不存在,则从Http Request中的accept-language header中读取;你可以通过设置CookieLocaleResolver的cookieName和cookieMaxAge属性来设置这个Cookie的属性名和最大的过期时间;你也可以通过SessionLocaleResolver的DefaultLocale属性来设置一个默认值;

    如何修改一个Request中的Locale,你可以通过直接调用LocaleResolver.setLocale()方法,也可以注册一个LocaleChangeInterceptor并将其应用到所有的请求,在LocaleChangeInterceptor中你可以通过一个paramName属性指定一个参数名,当LocaleChangeInterceptor在当前请求中检测到有这个参数出现时,则会使用这个参数的值作为当前请求的Locale;

  9. 我们通过LocalResolver能够获得客户端的Locale信息,那么我们就可以使用这些Locale信息向用户渲染不同的内容,这里我们要使用Message Source,我们需要在Spring Container中创建一个名为messageSource的bean,该bean的类型是ResourceBundleMessageSource;我们需要设置这个bean的basename到适当的resource bundle,那么我们就可以在jsp文件中使用<spring:message code="message code"/>去获得message;
  10. 在Spring MVC的Web Application中,使用一个或多个ViewResolver将Handler Method返回的view name解析为一个View对象;Spring MVC提供了以下几个ViewResolver:
    • InternalResourceViewResolver:通过指定一个Prefix和Sufix属性将Handler Method返回的View name拼凑成一个View文件的路径,然后再找到该视图文件编译后生成一个类型为JstlView的对象,我们也可以通过设置InternalResourceViewResolver的viewClass属性来设置该对象的类型;InternalResourceViewResolver比较简单,但是只能在找到整个应用程序中内部存在的资源视图;InternalResourceViewResolver还可以解析Redirect视图,如果某个Handler Method返回一个redirect:XXX的视图名,InternalResourceViewResolver会将这个视图名解析为到redirect:后面那一部分代表的URL的请求;
    • XmlViewResolver:我们可以将视图以bean的形式创建在Spring Container中,然后我们可以使用XmlViewResolver将视图名解析为一个View Bean;这些View Bean可以定义在当前的配置文件中,也可以定义在一个独立的Spring配置文件中,我们可以通过设置XmlViewResolver的location属性指定这个配置文件;默认是/WEB-INF/views.xml;
    • ResourceBundleViewResolver:我们可以通过ResourceBundleViewResolver来将一个Viewname解析为一个View对象,需要为ResourceBundleViewResolver对象的baseName属性指定一个Resource Bundle,这个Resource Bundle文件的格式应该是:
      {View name}.(class)={View class full name}
      {View name}.url={View file path}

    在一个SpringMVC的Web Application中可以创建多个ViewResolver的Bean,如果这种情况存在,你需要指定每一个ViewResolver的在Resolve View时的顺序,具体的做法是设置ViewResolver的order属性,这个属性的值越小代表具有越高的优先级;

  11. ContentNegotiatingViewResolver并不负责将一个View Name解析为一个View对象,它只负责根据Request决定客户端需要什么类型的Response,然后再委托给其他的ViewResolver处理,因此ContentNegotiatingViewResolver应在其他所有的ViewResolver之前执行,所以它应该具有最高优先级,它一般通过下面两个属性来判断客户端需要的内容:
    • 用户请求的URL中的扩展名;
    • 用户请求中的HTTP Accept Header。
  12. Exception Resolver和ContentNegotiatingViewResolver相似,它并不负责将一个View Name解析为一个View对象,它仅仅做的是根据Handler Method中抛出的异常返回一个View Name,然后再委托给其他的ViewResolver处理;你可以创建一个自定义的Exception Resolver,它必须实现自HandlerExceptionResolver接口,Spring MVC提供了一个内置的SimpleMappingExceptionResolver,这个类的ExceptionMappings属性允许你去配置映射不同的异常类型到不同的视图,如果某个异常类型不在这个映射中,你可以通过它的defaultErrorView属性指定一个默认的视图名;
    在视图页面,异常能通过能通过变量${exception}来访问;
    为了将Exception Resolver注册到Spring Container中,我们需要让配置类继承自WebMvcConfigurerAdapter,然后通过复写configureHandlerExceptionResolvers方法把Exception Resolver注册到这个添加到这个方法的参数里;

    注意,通过Exception Resolver方式能捕获Spring Container中所有Handler Method抛出的异常,如果仅仅想针对某一个Controller中所有Handler Method抛出的异常,我们可以在Controller中创建一个public方法,并标记上@ExceptionHandler annotation,这个annotation中可以指定要捕获的异常,如果不指定,则默认是所有异常;这个Public方法可以包含一个异常类型的参数,并返回一个字符串值,用于指定异常发生后要渲染的View Name;尽管使用@ExceptionHandler标记方法是非常的灵活和强大,但是缺点是你不得不把他们放在Controller里,并且仅仅针对controller中的Handler Method有效;如果我们想让它对其它所有的Controller中的Handler Method起作用,我们可以将它们提取到一个标记有@ControllerAdvice annotation的类中;

Spring学习笔记之五----Spring MVC的更多相关文章

  1. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  2. Java架构师之路 Spring学习笔记(一) Spring介绍

    前言 这是一篇原创的Spring学习笔记.主要记录我学习Spring4.0的过程.本人有四年的Java Web开发经验,最近在面试中遇到面试官总会问一些简单但我不会的Java问题,让我觉得有必要重新审 ...

  3. Spring 学习笔记(2) Spring Bean

    一.IoC 容器 IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期.也就是管 ...

  4. Spring学习笔记之Spring概述

    概述   Spring是一个java应用最广的开源框架,它是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Deve ...

  5. Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式

     本节主要内容:    1. 给MessageBean注入参数值    2. 测试Spring自动组件扫描方式    3. 如何控制ExampleBean实例化方式    4. 使用注解方式重构Jdb ...

  6. Spring学习笔记之 Spring IOC容器(一)之 实例化容器,创建JavaBean对象,控制Bean实例化,setter方式注入,依赖属性的注入,自动装配功能实现自动属性注入

    本节主要内容:       1.实例化Spring容器示例    2.利用Spring容器创建JavaBean对象    3.如何控制Bean实例化    4.利用Spring实现bean属性sett ...

  7. spring学习笔记之spring框架本质

    Spring框架的本质是,开发者在Spring配置文件中使用XML元素进行配置,实际驱动Spring执行相应的代码: 使用<bean.../>元素,实际启动Spring执行无参或有参构造函 ...

  8. Spring学习笔记2:Spring HelloWorld

    1:IntelliJ新建Maven工程 2:pom文件加入Spring依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  9. [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction

    1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...

随机推荐

  1. CSS 学习笔记

    0.CSS概念层叠样式表(Cascading Style Sheets),CSS的来历就不必多说了.可以简单的理解为万维网联盟(w3c)为了丰富HTML页面的布局和外观而指定的一种标准. 1.CSS实 ...

  2. 学习Http协议和当下主流的Rx+Retrofit的主流框架

    所有的劳累都会烟消云散了.不只在生活上,也对我的心态上发生了翻天覆地的变化.在和她在一起之前,我总觉得自己很小,不会去站在别人的角度替别人思考问题,没事就乱发脾气,抑或是一直沉迷于游戏.而和她在一起后 ...

  3. Python 中的枚举类型~转

    Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...

  4. NDK中可靠的获取JNIEnv*的方法

    使用NDK时,几乎任何方法都需要一个JNIEnv来调用.这个类是和线程相关的,如何可靠的获取它? 首先,作为NDK的so,必然有一个地方是由android系统调用的,这个调用将带来一个JNIEnv参数 ...

  5. c++输入一组整型数据 不知道长度 回车键结束 并将其存入数组当中

    #include "stdafx.h"#include<iostream>using namespace std;int main(){ int a[999];int ...

  6. centos7 使用systemd 自定义关机前脚本

    systemd (centos7) 需求,关机前执行脚本 关机脚本vi /usr/bin/shutdown_cust.sh#!/bin/bashecho "zhengchangguanji& ...

  7. 一个js简单的日历显示效果的函数

    用一个函数简单的实现一个月份的日历,效果如下: 这个日历效果有高亮显示,我实现的思维比较简单. 我把上面的日历效果用表格table生成,分成两个部分. 第一个部分:就是前面的第一排,我用一行<t ...

  8. doPost()和doGet()

    GET 请求的一些特点: GET 请求会有 cache GET 请求会保留在浏览历史中 GET 请求可以保存到书签 GET 请求不应用于处理敏感数据 GET 请求有长度限制 GET 请求应该只用于获取 ...

  9. Spring

    Spring 一个支持DI/IOC和AOP的开源容器框架 特点 DI/IOC DI 依赖注入(组件以特定方式接收来自容器的资源注入) IOC 控制反转(反转资源获取的方向) AOP 面向切面编程 开发 ...

  10. linux-------------计划任务crond:如何创建linux里面的计划任务

    1.centos下安装crond [root@localhost /]# yum -y install vixie-cron [root@localhost /]# yum -y install cr ...