• Spring MVC 使用介绍(四)—— 拦截器


    一、概述

    1、接口定义

    拦截器由HandlerInterceptor接口定义:

    public interface HandlerInterceptor {
        // 预处理方法
        boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
        // 后处理方法
        void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
        // 请求结束后处理方法
        void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
    }

    详细说明:

    • preHandle预处理方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器;返回值:
      • true:表示继续流程(如调用下一个拦截器或处理器)
      • false:表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应
    • postHandle后处理方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null
    • afterCompletion整个请求处理完毕处理方法,即在视图渲染完毕时调用,可以进行性能监控或资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion

    2、运行流程

    正常流程:

                             

    中断流程:

                             

    详细可参考DispatcherServlet.doDispatch()方法源码

    二、简单示例

    拦截器

    spring提供HandlerInterceptorAdapter适配器,提供HandlerInterceptor接口空的实现,允许我们只实现需要的方法,因此拦截器可继承自该接口

    public class TestInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("this is preHandle");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("this is postHandle");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("this is afterCompletion");
        }
    }

    控制器

    public class TestController2 implements Controller {
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            System.out.println("this is TestController2");
            return new ModelAndView("hello2");
        }
    }

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                       
            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <display-name>Archetype Created Web Application</display-name>
    
        <servlet>  
            <servlet-name>test-servlet</servlet-name>  
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>  
        </servlet>  
        <servlet-mapping>  
            <servlet-name>test-servlet</servlet-name>  
            <url-pattern>/</url-pattern>  
        </servlet-mapping> 
    </web-app>

    spring-mvc.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" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
               http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
              
        <!-- HandlerMapping -->  
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
            <property name="interceptors">  
                <list>  
                   <ref bean="testInterceptor"/>  
                </list>  
            </property>  
        </bean>  
           
        <!-- HandlerAdapter -->  
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> 
        
        <!-- ViewResolver -->  
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
            <property name="prefix" value="/WEB-INF/jsp/"/>  
            <property name="suffix" value=".jsp"/>  
        </bean>  
        
        <bean name="/hello2" class="cn.matt.controller.TestController2"/>
        
        <bean name="testInterceptor" class="cn.matt.interceptor.TestInterceptor"/>
        
    </beans>

    hello2.jsp

    <%@ page language="java" %>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
        hello2
    </body>
    </html>

    访问http://localhost:8080/myweb/hello2,控制台输出:

    this is preHandle
    this is TestController2
    this is postHandle
    this is afterCompletion

    推荐能使用servlet规范中的过滤器Filter实现的功能就用Filter实现,因为HandlerInteceptor只有在Spring Web MVC环境下才能使用,因此Filter是最通用的、最先应该使用的,详细使用可参考javaweb学习总结(四十二)——Filter(过滤器)学习

    参考:

    第五章 处理器拦截器详解——跟着开涛学SpringMVC

    javaweb学习总结(四十二)——Filter(过滤器)学习

  • 相关阅读:
    SharePoint 2010 Crawl Component Stuck in “Recovering” status
    什么是Named Pipes
    请不要修改FIM的配置, 否则SharePoint的User Profile无法获得微软支持
    经典的SharePoint 2010升级中的多核CPU冲突问题
    怎样才能比较方便地查看PowerShell里返回回来的对象的每个成员及它们的值呢?
    如何打开证书控制台
    浏览器: F5 和 Ctrl+F5的区别
    关于用户角色权限管理的探讨
    支付宝接口源代码
    海量数据处理
  • 原文地址:https://www.cnblogs.com/MattCheng/p/9171664.html
Copyright © 2020-2023  润新知