SpringMVC

拦截器

  Spring MVC也可以使用拦截器对请求进行拦截处理,可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口中的个方法也可以继承HandlerInterceptorAdapter 适配器类按照需要那个方法,就实现哪个方法

过滤器与拦截器区别

  过滤器:过滤器在Servlet之前操作
  拦截器:拦截器在Servlet之后,请求处理器(Controller)之前操作。

拦截器三个方法

  ① preHandle():这个方法在(Controller)处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。如果该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回 true;如果不需要再调用其他的组件去处理请求,则返回false。(如果返回false则后续操作都不再执行,类似于过滤器的 doFilter 所以正常情况下不要返回 false)

  ② postHandle():这个方法在(Controller)处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前(在视图渲染之前)被调用,在该方法中对用户请求request进行处理。

  ③ afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后(转发|重定向 之后)被调用,可以在该方法中进行一些资源清理关闭的操作。

配置拦截器

<mvc:interceptors>
<!-- 为所有请求设置拦截器 也可用 ref 引用已经装配好的拦截器-->
<bean id="firstHandlerInterceptor" class="main.controller.FirstHandlerInterceptor"></bean>
<mvc:interceptor>
<!-- 表示指定拦截器只拦截/test/下的所有请求-->
<mvc:mapping path="/test/**/"/>
<!-- 表示访问/test/test.do的请求不会触发拦截器-->
<mvc:exclude-mapping path="/test/test.do"/>
       <!-- 为指定的请求设置拦截器 也可用 ref 引用已经装配好的拦截器-->
       <bean id="testInterceptor" class="main.controller.TestInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

 程序执行顺序

  1. preHandle():执行请求处理器的请求(Controller)方法之前执行。 
  2. 执行请求处理器的请求(Controller)方法
  3. postHandle():执行请求处理器的请求(Controller)方法之后,在视图渲染之前。
  4. 视图渲染
  5. afterCompletion():视图渲染(转发|重定向)之后执行。

多个拦截器的执行流程

  当存在多个拦截器时的执行顺序,由配置的先后顺序决定。(preHandle() 先配置,先执行) 
  preHandle():与拦截器配置的先后顺序一致
  postHandle():与拦截器配置的先后顺序相反。底层倒序循环调用的
  afterCompletion():与拦截器配置的先后顺序相反。

preHandle()返回值为false时的工作原理

  第一个拦截器的preHandle()的返回值为false:
    只执行第一个拦截器的prehandle()方法,执行完,return;(后续的方法都不执行) 
  不是第一个拦截器的preHandle()的返回值为false: 
    当前拦截器之前的拦截器的afterCompletion()都会被执行。

  当两个拦截器的 preHandle() 方法都返回 true 时,按照虚线路执行

  当第二个拦截器 preHandle() 方法返回 false 时按照实现路线执行

异常处理

  在SpringMVC中,无论请求控制器中是否存在异常,都会返回ModelAndView对象

  Spring MVC 通过 HandlerExceptionResolver  处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常

  DispatcherServlet  默认装配的 HandlerExceptionResolver 有 DefaultHandlerExceptionResolver 解析器会自动将标准的Spring MVC异常解析为HTTP错误状态码

  使用 <mvc:annotation-driven/> 配置会装配Spring3.0后新增的异常解析器,实现更精细化处理。如果希望对所有异常进行统一处理或指定某一异常跳转页面,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,可实现跳转到指定页面,并报告异常.

配置异常解析器

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 为所有异常定义默认的处理页面,exceptionMappings未定义的,
value表示跳转页面,至于文件路径和后缀已经在 viewResolver 中指定-->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,被存放到 request 域中-->
<property name="exceptionAttribute" value="exception"></property>
<!-- 需要特殊处理的异常,全类名作为key,异常页文件名作为值,可将不同的异常映射到不同的页面上-->
<property name="exceptionMappings">
<props>
<prop key="java.lang.NullPointerException">nullPointer</prop>
</props>
</property>
</bean>

<mvc:annotation-driven/>

  是spring MVC为@Controllers分发请求所必须的,即启用注解驱动,解决了@Controller注解使用的前提配置。

  同时它还提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB,读写JSON的支持(Jackson)。

  它会自动为我们注册了很多的Bean,最重要的就是RequestMappingHandlerMappingRequestMappingHandlerAdapter

    第一个是HandlerMapping的实现类,它会处理@RequestMapping 注解,并将其注册到请求映射表中。
    第二个是HandlerAdapter的实现类,它是处理请求的适配器,说白了,就是确定调用哪个类的哪个方法,并且构造方法参数,返回值。

  简单的说,用什么注解,就需要声明对应的BeanPostProcessor。而Spring为我们提供了一种极为方便注册这些BeanPostProcessor的方式,即使用各种标签来隐式地向 Spring 容器注册

Spring工作流程

  相关类

    HandlerMapping(请求处理器的映射对象):定义了一个所有请求和请求处理器对象之间的映射关系对象

    HandlerExecutionChain(请求处理器执行链对象):定义了 当前请求处理器对象,和所有拦截器对象。

    HandlerAdapter(请求处理器的适配器对象):调用当前请求处理器的请求方法。

  执行流程对应下图理解

    1)用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获

    2)DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI):判断请求URI对应的映射
      ① 不存在:
        再判断是否配置了 mvc:default-servlet-handler:
        如果没配置,则控制台报映射查找不到,客户端展示404错误
        如果有配置,则执行目标资源(一般为静态资源,如:JS,CSS,HTML)
      ② 存在:
        执行下面流程

    3)根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;

    4)DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。

    5)如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法【正向】

    6)提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
      ① HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
      ② 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
      ③ 数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
      ④ 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

    7)Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;

    8)此时将开始执行拦截器的postHandle(...)方法【逆向】

    9)根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet,根据Model和View,来渲染视图

    10)在返回给客户端时需要执行拦截器的AfterCompletion方法【逆向】

    11)将渲染结果返回给客户端

Spring与SpringMVC

  spring容器与springMVC容器对象的关系

    springMVC容器对象,默认交个DispatcherServlet管理

    spring容器对象,需要我们管理(交给Listener管理)

  spring容器对象描述

    Root WebApplicationContext: root of context hierarchy

  springMVC容器对象描述

    WebApplicationContext for namespace 'springDispatcherServlet-servlet':root of context hierarchy

  spring容器对象是父,springMVC容器对象是子。子类可以直接调用父类方法。

  SpringMVC 的 IOC 容器中的 bean 可以引用 Spring IOC 容器中的 bean.反之则不行. 

  在web应用下,获取spring容器对象方式

ServletContext servletContext = httpSession.getServletContext();
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);

  在web应用下,获取springMVC容器对象可直接通过装配属性的方式获取

    @Autowired
private XmlWebApplicationContext context;

配置文件

  若 Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描组件的包有重合的部分, 就会导致有的 bean 会被创建 2 次,可通过一个包含一个排除的方式解决

Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程的更多相关文章

  1. java框架之Struts2(4)-拦截器&标签库

    拦截器 概述 Interceptor (拦截器):起到拦截客户端对 Action 请求的作用. Filter:过滤器,过滤客户端向服务器发送的请求. Interceptor:拦截器,拦截的是客户端对 ...

  2. java框架篇---struts实现拦截器

    Struts2的拦截器和Servlet过滤器类似.在执行Action的execute方法之前,Struts2会首先执行在struts.xml中引用的拦截器,在执行完所有引用的拦截器的intercept ...

  3. springmvc中拦截器与springmvc全局异常处理器的问题

    最近在做一个练手的小项目, 系统架构中用了springmvc的全局异常处理器, 做了系统的统一异常处理. 后来加入了springmvc的拦截器, 为了一些需求, 在拦截器中的 preHandle 方法 ...

  4. SpringMVC经典系列-14自己定义SpringMVC的拦截器---【LinusZhu】

    注意:此文章是个人原创.希望有转载须要的朋友们标明文章出处.假设各位朋友们认为写的还好,就给个赞哈.你的鼓舞是我创作的最大动力,LinusZhu在此表示十分感谢,当然文章中如有纰漏,请联系linusz ...

  5. SpringMVC:拦截器

    SpringMVC:拦截器   概述 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理.开发者可以自己定义一些拦截器来实现特定的功能. 过 ...

  6. springmvc的拦截器

    什么是拦截器                                                         java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...

  7. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  8. SpringMVC利用拦截器防止SQL注入

    引言 随着互联网的发展,人们在享受互联网带来的便捷的服务的时候,也面临着个人的隐私泄漏的问题.小到一个拥有用户系统的小型论坛,大到各个大型的银行机构,互联网安全问题都显得格外重要.而这些网站的背后,则 ...

  9. SpringMVC——实现拦截器

    1. SpringMVC拦截器的概念与Struts2相同 2. 实现拦截器 (1) 项目结构 (2) 实现HandlerInterceptor接口 package com.zhengbin.contr ...

随机推荐

  1. linux 选择 ioctl 命令

    在为 ioctl 编写代码之前, 你需要选择对应命令的数字. 许多程序员的第一个本能的反 应是选择一组小数从0或1 开始, 并且从此开始向上. 但是, 有充分的理由不这样做. ioctl 命令数字应当 ...

  2. 关于better-scroll的使用注意事项

    better-scroll的原理 1.什么是 better-scroll? better-scroll 是一个移动端滚动的解决方案,它不仅可以做普通的滚动列表,还可以做轮播图.picker 等等. 2 ...

  3. jQuery 工具类函数-使用$.extend()扩展Object对象

    除使用$.extend扩展工具函数外,还可以扩展原有的Object对象,在扩展对象时,两个对象将进行合并,当存在相同属性名时,后者将覆盖前者,调用格式为: $. extend (obj1,obj2,… ...

  4. jQuery 工具类函数-检测两个节点的包含关系

    调用名为$.contains的工具函数,能检测在一个DOM节点中是否包含另外一个DOM节点,如果包含,返回true,否则,返回false值,调用格式为: $.contains (container, ...

  5. 在eclipse动态网页项目中,编写web.xml时,servlet标签报错.

    cvc-complex-type.2.4.b: The content of element 'servlet' is not complete. One of '{"http:// jav ...

  6. 2018-2-13-WPF-异常-NativeWPFDLLLoader.LoadNativeWPFDLL

    title author date CreateTime categories WPF 异常 NativeWPFDLLLoader.LoadNativeWPFDLL lindexi 2018-2-13 ...

  7. Strongly Connected Tournament

    题解: 有一个很重要的性质就是 对于一张完全强联通图来说 一定有一个强联通分量入度为0(或者出度为0) 然后就一些计数题的基本套路 https://www.cnblogs.com/onioncyc/p ...

  8. HMaster/HRegion Server 工作原理

      1.HBase系统架构       2. HRegion Sever架构图 0.94之前的版本 0.96+的版本 WAL: 即Write Ahead Log, 是HDFS上一个文件,早期版本中称为 ...

  9. 关于python2和python3除法的区别

    在Python2中,除法的取值结果取整数 >>> 9/2 4 而在Python3中,除法/的结果包含小数,如果只想取整数需要使用// >>> 9/2 4.5 > ...

  10. SpringBoot中的五种对静态资源的映射规则

    目录 1.​ webjars:以jar包的方式引入静态资源 2./** 访问当前项目的任何资源 3.首页index.html,被" /** "映射 4.自定义图标 / favico ...