Java自学之SpringMVC:拦截器

本文详细解析了Spring MVC框架下拦截器的工作原理,重点介绍了自定义拦截器的实现过程及其在请求处理中的执行顺序。通过具体示例,展示了如何创建并配置拦截器,以及它在Controller前后的方法调用顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习目的:了解拦截器的执行顺序。本次学习基于zhuanlan.zhihu.com/p/10

Part 1

准备拦截器类:IndexInterceptor

package interceptor;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

public class IndexInterceptor extends HandlerInterceptorAdapter {

    /**
     * 在业务处理器处理请求之前被调用
     * 如果返回false
     *      从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链。
     * 如果返回true
     *      执行下一个拦截器,直到所有的拦截器都执行完毕
     *      再执行被拦截的Controller
     *      然后进入拦截器链
     *      从最后一个拦截器往回执行所有的postHandle()
     *      接着从最后一个拦截器往回执行所有的afterCompletion()
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
        System.out.println("preHandle(),在访问Controller之前被调用");
        return  true;
    }

    /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作
     * 可在modelAndView中加入数据,比如当前时间
     */
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
        modelAndView.addObject("date","由拦截器生成的时间:" + new Date());
    }

    /**
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
     *
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
     */
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

        System.out.println("afterCompletion(), 在访问视图之后被调用");
    }
}

Part 2

配置拦截器

修改springmvc-servlet.xml,以对/index路径进行拦截

如果要拦截其他路径:

/** 拦截所有

/category/** 拦截/category路径下的所有

<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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="controller" />

	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   		<property name="prefix" value="/WEB-INF/page/" />
  		<property name="suffix" value=".jsp" />
	</bean>

	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

	<!-- 	<bean id="simpleUrlHandlerMapping"
            class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/index">indexController</prop>
                    <prop key="/hello">helloController</prop>
                </props>
            </property>
        </bean>
        <bean id="indexController" class="controller.IndexController"></bean>
        <bean id="helloController" class="controller.HelloController"></bean> -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/index"/>
			<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
			<bean class="interceptor.IndexInterceptor"/>
		</mvc:interceptor>
		<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
	</mvc:interceptors>
</beans>

Part 3

修改index.jsp,新增一行<p>${date}</p>,用于打印拦截器添加的时间。

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" isELIgnored="false"%>

<h1>${message}</h1>
<p>${date}</p>

Part 4

运行测试

v2-5b66655c5a616538d4b059f0554f2955_b.jpg

Part 5

个人总结:执行流程

v2-0dc2374b6a825487922923f8544dd0ff_b.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值