springboot实现拦截器、过滤器、监听器

此篇记录Springboot实现拦截器、过滤器、监听器。

拦截器

一、创建拦截器

例如:拦截没有登录的用户跳转登录界面

首先创建一个登录拦截器LoginInterceptor继承HandlerInterceptor然后实现父类的方法:

preHandle   在请求处理之前进行调用(Controller方法调用之前)
  返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
postHandle  在请求处理之后进行调用(Controller方法调用之后)
afterCompletion  整个请求处理完毕回调方法,即在视图渲染完毕时回调,

如果要拦截没有登录用户则需要在请求处理之前进行判断,所以实现preHandle方法,例如:

拦截器代码如下:

package com.wh.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @Description //TODO
 * @Author wanghao
 * @Date 2019-09-10 22:25
 **/
@Component
public class LoginInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("进入拦截器,访问的url路径为:"+request.getServletPath());
        String user = (String) request.getSession().getAttribute("userInfo");
        System.out.println("出去拦截器,获取的user为:"+user);
        return !StringUtils.isEmpty(user);
    }


}

 

二、配置config管理类

package com.wh.config;


import com.wh.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description //TODO
 * @Author wanghao
 * @Date 2019-09-10 22:40
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
        .excludePathPatterns("/login");
    }
}

三、测试

 

 

 

 

 

 

首先进入test路径打印如下:

 

 

 

页面返回为空。是因为没有userInfo存在,所以被拦截了。

然后访问login,set用户信息,再次进入 test

 

 

 如上全部测试打印信息,第一次没有user,所以被拦截了。进入login方法后,set了user,就放行了。

如果我们拦截后进行信息打印或者跳转登录页面,都可以进行修改返回的操作。如下图所示;

 

 

 

 例如访问test打印的是:

四、多个拦截器执行顺序

添加的顺序进行改变后,打印信息如下:

 

 

所以执行顺序和添加顺序有关,例如先添加的1、然后添加的2,3则执行顺序为:

过滤器

过滤器与拦截器配置类似,

一、新建过滤器

package com.wh.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class MyFilter implements Filter {

    Logger logger = LoggerFactory.getLogger(MyFilter.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest  request1 = (HttpServletRequest) request;
        logger.info("进入MyFilter 请求URl: "+ request1.getContextPath());
     // 注:如果不下下面这一句则不会往后面执行,相当于被拦截了 chain.doFilter(request, response); } @Override
public void destroy() {} }

二、配置过滤器,依然在上面拦截器的配置类里面配置如下代码:

package com.wh.config;


import com.wh.filter.MyFilter;
import com.wh.filter.MyFilter2;
import com.wh.interceptor.LoginInterceptor;
import com.wh.interceptor.SensitiveInfoInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description //TODO
 * @Author wanghao
 * @Date 2019-09-10 22:40
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {


    @Autowired
    LoginInterceptor loginInterceptor;
    @Autowired
    SensitiveInfoInterceptor sensitiveInfoInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login
//        registry.addInterceptor(sensitiveInfoInterceptor).addPathPatterns("/**")
//                .excludePathPatterns("/login");
//        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
//        .excludePathPatterns("/login");

    }

    @Bean
    public FilterRegistrationBean<MyFilter> filter1() {
        FilterRegistrationBean<MyFilter> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(new MyFilter());
        // /*  所有请求
        filterRegBean.addUrlPatterns("/*");
        filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
        return filterRegBean;
    }


}

三、结果

如下图所示:正常进入过滤器,

 

四、过滤链

新建MyFilter2此处略

然后在config中添加MyFilter的配置如下:

package com.wh.config;


import com.wh.filter.MyFilter;
import com.wh.filter.MyFilter2;
import com.wh.interceptor.LoginInterceptor;
import com.wh.interceptor.SensitiveInfoInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description //TODO
 * @Author wanghao
 * @Date 2019-09-10 22:40
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {


    @Autowired
    LoginInterceptor loginInterceptor;
    @Autowired
    SensitiveInfoInterceptor sensitiveInfoInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login
//        registry.addInterceptor(sensitiveInfoInterceptor).addPathPatterns("/**")
//                .excludePathPatterns("/login");
//        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
//        .excludePathPatterns("/login");

    }

    @Bean
    public FilterRegistrationBean<MyFilter> filter1() {
        FilterRegistrationBean<MyFilter> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(new MyFilter());
        // /*  所有请求
        filterRegBean.addUrlPatterns("/*");
        // order 越小优先级越高
        filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
        return filterRegBean;
    }
    @Bean
    public FilterRegistrationBean<MyFilter2> filter2() {
        FilterRegistrationBean<MyFilter2> filterRegBean = new FilterRegistrationBean<>();
        filterRegBean.setFilter(new MyFilter2());
        // /*  所有请求
        filterRegBean.addUrlPatterns("/*");
        // order 越小优先级越高
        filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
        return filterRegBean;
    }


}

结果如下图所示;优先执行了Order小的一个,Filter2,所以配置多个过滤器的时候,Order越小则优先级越高。

 常用的字符乱码过滤器:

    @Bean
    public FilterRegistrationBean characterEncodingFilterRegister(){
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
        CharacterEncodingFilter characterEncodingFilter=new CharacterEncodingFilter();
        characterEncodingFilter.setForceEncoding(true);
        characterEncodingFilter.setEncoding("UTF-8");
        filterRegistrationBean.setFilter(characterEncodingFilter);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE+1);
        return  filterRegistrationBean;
    }

不过一般都在配置文件这样配置:

# 设置请求响应的字符编码
  spring.http.encoding.charset=UTF-8
  spring.http.encoding.enabled=true
  spring.http.encoding.force=true

监听器

一、创建监听器

package com.wh.listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * 创建监听Session
 */
public class MyHttpSessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("创建Session 请求Url" + se.getSession().getServletContext().getContextPath());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("销毁Session");
    }
}

二、配置config

    @Bean
    public ServletListenerRegistrationBean listener1(){
        ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();
        srb.setListener(new MyHttpSessionListener());
        return  srb;
    }

三、结果

 

 

 

四、监听器补充

1.ServletContextListener -- 监听servletContext对象的创建以及销毁

    1.1    contextInitialized(ServletContextEvent arg0)   -- 创建时执行

    1.2    contextDestroyed(ServletContextEvent arg0)  -- 销毁时执行

2.HttpSessionListener  -- 监听session对象的创建以及销毁

    2.2   sessionCreated(HttpSessionEvent se)   -- 创建时执行

    2.2   sessionDestroyed(HttpSessionEvent se) -- 销毁时执行

3.ServletRequestListener -- 监听request对象的创建以及销毁

    3.1    requestInitialized(ServletRequestEvent sre) -- 创建时执行

    3.2    requestDestroyed(ServletRequestEvent sre) -- 销毁时执行

4.ServletContextAttributeListener  -- 监听servletContext对象中属性的改变

    4.1    attributeAdded(ServletContextAttributeEvent event) -- 添加属性时执行

    4.2    attributeReplaced(ServletContextAttributeEvent event) -- 修改属性时执行

    4.3    attributeRemoved(ServletContextAttributeEvent event) -- 删除属性时执行

5.HttpSessionAttributeListener  --监听session对象中属性的改变

    5.1    attributeAdded(HttpSessionBindingEvent event) -- 添加属性时执行

    5.2    attributeReplaced(HttpSessionBindingEvent event) -- 修改属性时执行

    5.3    attributeRemoved(HttpSessionBindingEvent event) -- 删除属性时执行

6.ServletRequestAttributeListener  --监听request对象中属性的改变

    6.1    attributeAdded(ServletRequestAttributeEvent srae) -- 添加属性时执行

    6.2    attributeReplaced(ServletRequestAttributeEvent srae) -- 修改属性时执行

    6.3    attributeRemoved(ServletRequestAttributeEvent srae) -- 删除属性时执行

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 引用资料:

https://www.cnblogs.com/hhhshct/p/8808115.html

https://blog.csdn.net/m0_38075425/article/details/81164501

 

扩展资料:

HandlerInterceptorAdapter或HandlerInterceptor的区别

WebMvcConfigurationSupport和WebMvcConfigurer的区别

posted @ 2019-09-11 09:43  苦心明  阅读(638)  评论(0)    收藏  举报