【JavaWeb】过滤器、拦截器、ControllerAdvice、AOP的联系与区别

过滤器、拦截器、ControllerAdvice、AOP的联系与区别

1. 技术概述

1.1 过滤器

(1) 概述

​ 过滤器 Filter 是JavaWeb(Sevlet、Filter、Listener)三大组件之一,会将浏览器对服务器的资源请求先统一拦截,需要通过Filter才能访问到对应资源,访问操作结束后会回到过滤器再响应给浏览器。

image-20231129212537503

简单总结:

  • 来自J2EE中的Servlet技术
  • 实现原理:基于servlet的函数回调实现
  • 只可以获取到请求中的request和response,无法获取到响应方法的信息
  • 可以拦截所有请求
  • 支持使用xml配置和注解配置

(2) 使用流程

  1. 实现 Filter 接口,重写 doFilter 方法;

  2. 放行请求时调用chain.doFilter()方法;

  3. 启用过滤器,有三种方式,

    第一种是比较原始的xml配置(较为繁琐)

​ 第二种是使用注解 @WebFilter() ,并在启动类上添加@ServletComponentScan注解使用。

​ 第三种是直接使用@Component注解,这样的话@WebFilter配置的路径会失效,因为@WebFilter根本就没生效。

  1. 设置拦截路径,就是要拦截的那个url路径。

方式二示例:

// 1. 实现Filter接口,通过@WebFilter可以配置过滤范围、name等参数
@WebFilter(value = "/device/*",filterName = "myFilter",displayName = "thisIsFilter")
public class MyFilter implements Filter {
    
    // 销毁过滤器时调用的方法(默认不用实现)
    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    // 初始化方法(默认不用实现该方法)
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 请求接口前操作
        // 调用接口方法前需要执行的代码
		filterChain.doFilter(servletRequest,servletResponse);  // 放行到下一个过滤器
        // 请求接口后操作
        // 调用接口方法后需要执行的代码
    }
}
====
// 2.
@ServletComponentScan  // 如果不标准该注解将Filter将不会生效
@SpringBootApplication
public class DisplayCoreApplication {

    public static void main(String[] args) {
        SpringApplication.run(DisplayCoreApplication.class, args);
    }

}

方式三示例:

// 1.实现Filter接口
public class MyFilter implements Filter {
    
    // 销毁过滤器时调用的方法(默认不用实现)
    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    // 初始化方法(默认不用实现该方法)
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain 	         filterChain) throws IOException, ServletException {
        // 请求接口前操作
        // 调用接口方法前需要执行的代码
		filterChain.doFilter(servletRequest,servletResponse);  // 放行到下一个过滤器
        // 请求接口后操作
        // 调用接口方法后需要执行的代码
    }
}

====== 
// 2. 创建Filter配置类,对自定义的Filter进行定义配置
@Configuration
public class FilterConfig {
    /**
     * 配置一个Filter注册器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean1() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter1());
        registrationBean.setName("filter1");
        //设置顺序 order越小,优先级越高
        registrationBean.setOrder(10);
        return registrationBean;
    }
    @Bean
    public FilterRegistrationBean filterRegistrationBean2() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter2());
        registrationBean.setName("filter2");
        //设置顺序
        registrationBean.setOrder(3);
        return registrationBean;
    }
    @Bean
    public Filter filter1() {
        return new MyFilter();
    }

    @Bean
    public Filter filter2() {
        return new MyFilter2();
    }
}

(3) 实现原理

​ 在我们自定义的过滤器中都会实现一个 doFilter()方法,这个方法有一个FilterChain 参数,而实际上它是一个回调接口。ApplicationFilterChain是它的实现类, 这个实现类内部也有一个 doFilter() 方法就是回调方法。

public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}

ApplicationFilterChain里面能拿到我们自定义的xxxFilter类,在其内部回调方法doFilter()里调用各个自定义xxxFilter过滤器,并执行 doFilter() 方法。

// 源码
public final class ApplicationFilterChain implements FilterChain {
// 
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private Servlet servlet;
public void doFilter(ServletRequest request, ServletResponse response) {
	internalDoFilter(request, response);
}

private void internalDoFilter(ServletRequest request, ServletResponse response) {
	if (this.pos < this.n) {   //获取第pos个filter    
		ApplicationFilterConfig filterConfig = this.filters[this.pos++];
		Filter filter = filterConfig.getFilter();
		filter.doFilter(request, response, this);             
	} else {
		this.servlet.service(request, response);
	}
 }
}

内部定义了ApplicationFilterConfig[] filters 过滤器配置列表,每一个ApplicationFilterConfig内部持有一个Filter实例,另一个比较重要的是Servlet,实例化后对应原生HttpServlet或SpringMVC的DispatcherServlet,当拦截器链路执行完成后,会调用Servlet中service方法做后续的Url路由映射、业务处理以及视图响应等流程

image-20231129220034399

1.2 拦截器

(1) 概述

​ 由Spring提供支持的一种动态拦截方法调用的机制,只对action请求起作用(个人理解就是只对SpringMVC的请求访问进行拦截)并且可以获得这些action请求的上下文信息,如参数,返回值等。

image-20231129221215231

  • 来自Spring,不依赖于servlet容器,但依赖于Spring
  • 实现原理:通过反射机制实现
  • 可以获取到Spring中存在的Bean,通过注入的方式
  • 只对action请求起作用,并可以获取到action请求的上下文

(2) 使用流程

  1. 实现 HandlerInterceptor 接口 或 继承 HandlerInterceptorAdapter 类,建议使用接口;
  2. 实现 preHandle 方法(在处理请求前运行),实现 postHandle 方法(在处理请求完毕后运行);
  3. 再新建一个类,继承 WebMvcConfigurer 接口,再实现addInterceptors方法,并在方法中注册该拦截器、配置拦截路径(不配置默认拦截所有请求);

示例:

@Slf4j
public class MyInterceptor implements HandlerInterceptor {

	@Override  // 目标资源方法执行前执行
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		log.info("before interceptor");
		return true;   // true 为放行, flase为不放行
	}

	@Override  //目标资源方法执行后执行
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 	          ModelAndView modelAndView) {
		log.info("after interceptor");
	}
    
     @Override //试图渲染完毕后运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}
====
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(handlerInterceptor())
                //配置拦截规则  addPathPatterns()配置拦截的请求  excludePathPatterns("/login") 配置放行的请求
                .addPathPatterns("/**")  
        		.excludePathPatterns("/login")}
    @Bean
    public HandlerInterceptor handlerInterceptor() {
        return new MyInterceptor();
    }
}

(3) 原理浅析

​ 浏览器发出的请求会先被过滤器拦截,然后进入到spring环境,tomcat不识别controller,但是识别servlet,spring的web环境提供了一个非常核心的servlet——DispatchServlet。由DispatchServlet转给Controller,在这之前会先被拦截器拦截执行preHandle方法,根据其返回值决定是否执行Controller方法。

image-20231129222355800

image-20231129221619431

1.3 @ControllerAdvice

1.4 AOP

2. 四者执行顺序

image-20231129222630462

Filte > 拦截器 > ControllerAdvice > AOP

3. 区别与应用场景总结

roller方法。

[外链图片转存中…(img-ihLRmE8W-1701268496160)]

[外链图片转存中…(img-w0sPrZst-1701268496161)]

1.3 @ControllerAdvice

1.4 AOP

2. 四者执行顺序

[外链图片转存中…(img-KTmihv7D-1701268496161)]

Filte > 拦截器 > ControllerAdvice > AOP

3. 区别与应用场景总结

image-20231129222739645

  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整全套资源下载地址:https://download.csdn.net/download/qq_27595745/70761177 【完整课程列表】 完整版Java web开发教程PPT课件 Java开发进阶教程 第01章 JavaScript简介以及基本语法(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第02章 Dom模型,控制客户端元素(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第03章 表单验证,常用函数(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第04章 自定义web服务器(共14页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第06章 SERVLET(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第07章 JSP语法及运行过程(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第08章 JSP内置对象(共22页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第09章 jstl、el、java bean(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第10章 过滤器、监听器、自定义标签(共19页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第11章 AJAX实现(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第12章 自定义mvc框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第13章 spring ioc aop(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第14章 spring mvc介绍,原理以及搭建(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第15章 spring mvc核心对象拦截器(共26页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第17章 自定义orm框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第18章 mybatis框架的搭建以及应用(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第19章 mybatis高级应用(共21页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第20章 数据库连接池,缓存(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第22章 常用框架的介绍以及环境搭建(共16页).pptx JS课程案例ebookHTML\网上书店需求文档.doc
引用中的代码展示了一个名为SysFilter的Java类,该类实现了Filter接口,用于进行登录拦截的过滤器。该过滤器的作用主要是拦截用户访问网站或管理员中心的请求,并根据用户的登录状态做出不同的响应。如果用户没有登录,则会将其重定向到错误页面;如果用户已登录但不是管理员,则同样不能进入管理员中心。 引用中提到了过滤器的一些常见用途,其中包括处理请求字符集、控制网页资源的访问权限以及敏感词屏蔽等功能。 过滤器的工作流程一般包括三个步骤:初始化(init)、拦截请求并处理(doFilter)、销毁(destroy)。在初始化阶段,可以进行一些必要的配置操作。在拦截请求并处理的阶段,可以对请求进行必要的验证、修改或重定向等操作。在销毁阶段,可以进行一些资源的释放或清理操作。 要实现一个登录拦截的过滤器,可以按照以下步骤进行: 1. 创建一个过滤器类,实现Filter接口,并完善其中的init、doFilter等方法。特别是在doFilter方法中,根据需要进行登录状态的判断和响应处理。 2. 如果使用注解的方式进行配置,可以在过滤器实现类的开头添加@WebFilter注解;如果使用web.xml进行配置,可以像配置Servlet一样进行配置。 3. 在过滤器中实现相应的登录拦截逻辑,根据用户的登录状态进行不同的处理,如重定向到登录页面或错误页面。 这样,当用户访问需要登录才能访问的网页资源时,过滤器会拦截请求并进行相应的登录拦截处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [javaweb网站登录框架实现:使用Filter过滤器实现登录拦截+使用JavaScript实现登录限制等(分管理员和用户)](https://blog.csdn.net/Xmumu_/article/details/120919687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【JavaWeb】用过滤器实现字符集设置和登录拦截](https://blog.csdn.net/csdn_inside/article/details/89081938)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值