SpringMVC学习总结(五).拦截器的使用

本文详细介绍了Spring MVC中自定义拦截器的使用,包括preHandle、postHandle和afterCompletion三个方法的执行顺序。通过实例测试展示了拦截器的配置和实际效果,并提供了源码分析,帮助理解其工作原理。

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

自定义拦截器

    • Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口

    – preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request 进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false

    – postHandle():这个方法在业务处理器处理完请求后,但DispatcherServlet向客户端返回响应前被调用,在该方法中对用户请求request进行处理。

    – afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

实例测试:

FirstInterceptor.java

package com.xyc.springmvc.interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * @ClassName:  FirstInterceptor   
 * @Description:拦截器 
 * @author: xyc 
 * @date:   2017年1月4日 下午9:26:59   
 *
 */
public class FirstInterceptor implements HandlerInterceptor {

    /**
     * 
     * <p>Title: preHandle</p>   
     * <p>Description: </p>   
     *  该方法在目标方法之前被调用.若返回值为 true, 则继续调用后续的拦截器和目标方法. 若返回值为 false, 则不会再调用后续的拦截器和目标方法. 
     *  可以考虑做权限. 日志, 事务等. 
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception   
     * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("[FirstInterceptor] preHandle");
        return true;
    }

    /**
     * 
     * <p>Title: postHandle</p>   
     * <p>Description: </p>   
     *  调用目标方法之后, 但渲染视图之前. 
     *  可以对请求域中的属性或视图做出修改. 当出异常的时候,不走这个方法,走下面的后置处理器
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception   
     * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("[FirstInterceptor] postHandle");

    }

    /**
     * 
     * <p>Title: afterCompletion</p>   
     * <p>Description: </p>  
     * 渲染视图之后被调用. 释放资源 
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception   
     * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) throws Exception {
        System.out.println("[FirstInterceptor] afterCompletion");

    }

}
配置:

<!-- 配置拦截器 -->
<mvc:interceptors>
	<bean class="com.xyc.springmvc.interceptor.FirstInterceptor"></bean>
</mvc:interceptors>


目标方法:

/**
 * 
 * @Title: testInterceptor   
 * @Description: 测试拦截器的目标方法
 * @param: @return      
 * @return: String      
 * @throws
 */
@RequestMapping("/testInterceptor")
public String testInterceptor(){
    System.out.println("testInterceptor");
    return "success";
}

请求http://localhost:8081/testInterceptor之后,测试结果:



拦截器方法执行的顺序:



配置拦截器

新增SecondInterceptor拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
	<!-- 拦截所有请求 -->
	<bean class="com.xyc.springmvc.interceptor.FirstInterceptor"></bean>
	<!-- 拦截指定资源    配置拦截器作用的路径-->
	<mvc:interceptor>
		<mvc:mapping path="/testInterceptor"/>
		<bean class="com.xyc.springmvc.interceptor.SecondInterceptor"></bean>
		 <!-- 配置拦截器不作用的路径 -->
		<!-- <mvc:exclude-mapping path=""/> -->
	</mvc:interceptor>
</mvc:interceptors>

两个拦截器都返回true执行结构和执行顺序:


源码分析:
















所以当第一个拦截器返回false时候,结果:


当第第一个拦截器true,第二个拦截器false时,结果:





补:当过滤器、拦截器、切面同时存在的时候,是什么样子的执行顺序呢?


过滤器先执行,拦截器之后执行,遇到异常之后,先被异常处理机制捕获处理,再到切面执行后执行具体的handler,  当然遇到异常的时候最先被切面捕获,之后到异常处理机制


1.过滤器执行链之前(chain.doFilter之前)
2.拦截器前置通知
3.切面(没分前置通知,后置通知,只测试了一个环绕通知)
4.具体的handler
5.拦截器postHandle
6.拦截器后置处理器
7.过滤器chain.doFilter之后


过滤器里面拿不到具体执行的handler名称,方法等, 拦截器里面可以拿到但是拿不到参数, 切面所有的都可以拿到
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值