SpringMVC:( 过滤器和拦截器 )详解

1. 图解

  在请求到达容器前,进入Filter过滤器链,执行完过滤器链上每个Filter.doFilter()方法后,进入Servlet.service()方法,然后由dispatcher分发器将请求方法给对应映射成功的处理器controller,在进入controller具体方法之前,会被先进入Interceptor.preHandler()方法,然后再进入controller的具体返回,执行之后进入Interceptor.postHandler()这里主要是拦截了controller方法执行之后到返回的数据模型到达视图解析器之前,接着进入Interceptor.afterCompletion()方法,主要可以操作返回客户端之前的逻辑,最后返回到过滤链中各个Filter的调用点,可以处理返回到客户端的跳转等逻辑。

2. 什么是过滤器(Filter)

过滤器:

  过滤器拦截的是request请求,有初始化方法和销毁方法,拦截的是Request、Response请求,粒度很大。

  过滤器实现Filter接口并提供了三个方法,分别是初始化(init)方法,具体拦截函数(dofilter)方法和销毁(destroy)方法,过滤器随着容器的启动和销毁而初始化和销毁,依赖于servlet容器,

过滤器拦截的是请求地址(Request、Response)请求,过滤器运行在servlet操作之前,比如对请求参数进行校验,或者设置、检验头部信息,再或者对一些非法行为进行校验。

具体代码实现

package com.example.demo.modules.filter;

import javax.servlet.*;
import java.io.IOException;

/**
 * @Description:
 * @date :  2022/9/26
 */
public class MyFilter implements Filter {
 
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("过滤器销毁方法");
	}
 
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器具体对请求的操作, 比如验证Token,权限,路径等");
		chain.doFilter(request, response);
	}
 
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("过滤器初始化方法");
	}
 
}
package com.example.demo.modules.filter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;

/**
 * 创建过滤器myFilter,并且添加到FilterRegistrationBean
 * 注入到IOC中
 * @Description:
 * @date :  2022/9/26
 */
@Configuration
public class ConfigBean {

    // 把自定义的过滤器类加入过滤器链中
	@Bean
	public FilterRegistrationBean filterRegistrationBean(){
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        // 将自定义过滤器加入到过滤器链中
		filterRegistrationBean.setFilter(myFilter());
        // 自定义命名
		filterRegistrationBean.setName("myFilter");
        // 过滤的路径 /*:全部
		filterRegistrationBean.addUrlPatterns("/*");
		filterRegistrationBean.setOrder(1);
		return filterRegistrationBean;
	}

    // 注入到IOC容器中
	@Bean
	public Filter myFilter(){
		return new MyFilter();
	}
}

 

3. 什么是拦截器(Interceptor)

拦截器:

  拦截器基于Java的jdk动态代实现的,由HandlerInterceptor接口实现,由于是spring容器的接口,所以它是依赖于spring容器,并不依赖于servlet容器。

  拦截器的原理是AOP的思想,可以对某一个方法进行横切,做一些业务逻辑。主要针对于contraller方法,它能获取到所有的类,对类里面所有的方法实现拦截,粒度更小。

具体代码实现

package com.example.demo.modules.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @Description:
 * @date :  2022/9/26
 */
@Slf4j
public class CustomHandlerInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
		log.info("Request请求调用之前");
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
		log.info("Request请求调用之后");
	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
		log.info("afterCompletion:请求调用完成后回调方法,即在视图渲染完成后回调");
	}
}
package com.example.demo.modules.interceptor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description:
 * @date :  2022/9/26
 */
@Configuration
public class WebConfig extends WebMvcConfigurer {

    // 添加自定义拦截器
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		//super.addInterceptors(registry);
        // 拦截路径 /*:全部
		registry.addInterceptor(getHandlerInterceptor()).addPathPatterns("/*");
	}

    // 注入到IOC
	@Bean
	public static HandlerInterceptor getHandlerInterceptor(){
		return new CustomHandlerInterceptor();
	}
}

4. 小结

  过滤器是servlet中的接口,主要可以用于在请求进入到servlet之前拦截请求HttpServletRequest并根据需要进行一些检查等逻辑操作,也可以在HttpServletResponse返回到客户端之前进行一些逻辑操作。

​  拦截器是spring中的接口,所以它可以获取到spring中的一些bean和其他的一些资源,在面向切面编程中应用比较广,拦截其实就是一种AOP策略。

 

文章整合至:https://blog.csdn.net/weixin_44253023/article/details/121940932https://blog.csdn.net/huyiju/article/details/83028720https://blog.csdn.net/csdnjiamin/article/details/109523151

posted @ 2022-09-26 11:26  怒吼的萝卜  阅读(1575)  评论(0编辑  收藏  举报