面试之过滤器与拦截器

首先呢,我们先来理解概念
(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)

(2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预他,通过验证的少点,顺便干点别的东西)。

拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.。

拦截器的使用场景:
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;

3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。

过滤器的使用场景:

1、防止未登录就进入界面

2、控制应用编码

3、过滤敏感词汇等场景

springboot过滤器代码示例:
1、@WebFilter注解加@ServletComponentScan注解直接就可以创建过滤器

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/*定义自己的过滤器实现filter接口*/
@WebFilter(filterName = "loginFilter",urlPatterns = "/*")
public class LoginFilter implements Filter {
	/*服务停止后被执行:销毁*/
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
		System.out.print("哎呀,我要被销毁了!!!");
	}
    /*请求之前被执行:业务逻辑处理*/
	@Override
	public   void  doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
	System.out.println(servletRequest);	
		// TODO Auto-generated method stub
		 System.out.println("哈哈 被拦截了吧!!!+1");
		 boolean flag=false;
        
        	 filterChain.doFilter(servletRequest,servletResponse);
       
		
		 System.out.println("哈哈 被拦截了吧!!!+2");


	}
    /*服务启动的事后被执行:初始化*/
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		 System.out.println("哎呀,我被生出来了!!!");

		     }


}
import java.util.HashMap;
import java.util.Map;

import javax.servlet.annotation.ServletSecurity;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/*@ServletComponentScan 配置到springboot中*/
@SpringBootApplication
@ServletComponentScan
public class HelloSpringBoot {
	/*
	 @RequestMapping("/index")
	    @ResponseBody
	    public String index(){
	        return "Hello Word!";
	    }
	 
	 @RequestMapping("/getMap")
	    @ResponseBody
	      public Map<Object,Object> getMap(){
	          Map<Object,Object> m = new HashMap<>();
	         m.put(1, "a");
	         m.put(2, "b");
	          m.put(3, "c");
	         return m;
	      }
	 */
	 
	    //入口程序
	    public static void main(String[] args) {
	        //主函数运行springboot项目
	        SpringApplication.run(HelloSpringBoot.class, args);
	    }


}

springboot拦截器代码示例:

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

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/*

  • 实现handlerInterceptor 接口创建拦截器
  • */

public class MyInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
    System.out.println(">>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");

    return true;// 只有返回true才会继续向下执行,返回false取消当前请求
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    System.out.println(">>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    System.out.println(">>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
}

}

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/*
 * 实现WebMvcConfigurer接口配置拦截器
 * @Configuration 、@Configuration配置spring并启动spring容器 启动初始化");
 * 
 * */
@Configuration
public class WebMvcConfig extends  WebMvcConfigurerAdapter  {

	@Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则
        // excludePathPatterns 用户排除拦截
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
       // registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }

}

拦截器与过滤器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  ④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
  ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
拦截器可以获取ioc中的service bean实现业务逻辑,拦截器可以获取ioc中的service bean实现业务逻辑,拦截器可以获取ioc中的service bean实现业务逻辑。

过滤器和拦截器触发时机:

过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。过滤器的触发时机是容器后,servlet之前,所以过滤器的doFilter(
ServletRequest request, ServletResponse response, FilterChain chain
)的入参是ServletRequest ,而不是httpservletrequest。因为过滤器是在httpservlet之前。

在这里插入图片描述
在这里插入图片描述

参考:
https://www.cnblogs.com/panxuejun/p/7715917.html
https://juejin.im/post/6844904083917127693等

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值