springboot中的过滤器、拦截器、监听器整合使用

controller层

用于测试

@RestController
public class TestController {
    
    

    @GetMapping("/addSession")
    public String addSession(HttpServletRequest request) {
    
    
        HttpSession session = request.getSession();
        session.setAttribute("name", "dalaoyang");
        return "当前在线人数" + MyHttpSessionListener.online;
    }

    @GetMapping("/removeSession")
    public String removeSession(HttpServletRequest request) {
    
    
        HttpSession session = request.getSession();
        session.invalidate();
        return "当前在线人数" + MyHttpSessionListener.online;
    }

    @GetMapping("/online")
    public String online() {
    
    
        return "当前在线人数:" + MyHttpSessionListener.online + "人";
    }
}

过滤器

过滤器的英文名称为Filter,是Servlet技术中最实用的技术。如同它的名字一样,过滤器是处于客户端与服务器资源文件之间的一道过滤网,帮助我们过滤一些不符合要求的请求。通常它被用作Session校验,判断用户权限,如果不符合设定条件,就会被拦截到特殊的地址或者给予特殊的响应。 2. 使用过滤器 使用过滤器很简单,只需要实现Filter类,然后重写它的3个方法即可。 · init方法:在容器中创建当前过滤器的时候自动调用这个方法。 · destory方法:在容器中销毁当前过滤器的时候自动调用这个方法。 · doFilter方法:这个方法有3个参数,分别是ServletRequest、ServletResponse和FilterChain。可以从参数中获取HttpServletRequest和HttpServletResponse对象进行相应的处理操作。 接下来,我们直接创建一个过滤器MyFilter。这里做一些URL的拦截,如果符合条件,就正常跳转,如果不符合条件,就拦截到/online请求中。


public class MyFilter implements Filter {
    
    

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
        System.out.println("MyFilter被调用");
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
        //只有符合条件的可以直接请求,不符合的跳转到/online请求去
        String requestUri = httpServletRequest.getRequestURI();
        System.out.println("请求地址是:"+requestUri);
        if (requestUri.indexOf("/addSession") != -1
                || requestUri.indexOf("/removeSession") != -1
                || requestUri.indexOf("/online") != -1
                || requestUri.indexOf("/favicon.ico") != -1) {
    
    
            chain.doFilter(request, response);
        } else {
    
    
            wrapper.sendRedirect("/online");
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        //在服务启动时初始化
        System.out.println("初始化拦截器");
    }

    @Override
    public void destroy() {
    
    
        //在服务关闭是销毁
        System.out.println("销毁拦截器");
    }
}

拦截器

拦截器介绍

Java中的拦截器是动态拦截action调用的对象,然后提供了可以在action执行前后增加一些操作,也可以在action执行前停止操作。其实拦截器也可以做和过滤器同样的操作,以下是拦截器的常用场景。
登录认证:在一些简单应用中,可能会通过拦截器来验证用户的登录状态,如果没有登录或者登录失效,就会给用户一个友好的提示或者返回登录页面。
记录系统日志:在Web应用中,通常需要记录用户的请求信息,比如请求的IP、方法执行时常等,通过这些记录可以监控系统的状况,以便于对系统进行信息监控、信息统计、计算PV(Page View)和性能调优等。 · 
通用处理:在应用程序中可能存在所有方法都要返回的信息,这时可以使用拦截器来实现,省去每个方法冗余重复的代码实现。

使用拦截器

这里以使用Spring拦截器为例,在类上需要实现HandlerInterceptor类,并且重写类中的3个方法,分别是: · 
▶▶▶preHandle 在业务处理器处理请求之前被调用,返回值是boolean值,如果返回true,就进行下一步操作;若返回false,则证明不符合拦截条件。在失败的时候不会包含任何响应,此时需要调用对应的response返回对应响应。 ·

▶▶▶postHandle 在业务处理器处理请求执行完成后、生成视图前执行。这个方法可以通过方法参数ModelAndView对视图进行处理,当然ModelAndView也可以设置为null。 ·

▶▶▶afterCompletion 在DispatcherServlet完全处理请求后被调用,通常用于记录消耗时间,也可以进行一些资源处理操作。 接下来,创建一个自定义拦截器MyInterceptor,我们用这个拦截器打印请求的耗时,并且判断当前的浏览器是否存在Session。

@Component
public class MyInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("preHandle被调用");
        request.setAttribute("startTime", System.currentTimeMillis());
        //request.setAttribute将值添加到了http请求头上
        //request.getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 。
//request.setAttribute (“curruser”, curruser)这个方法是将curruser这个对象保存在request作用域中,然后在转发进入的页面就可以获取到你的值,
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("postHandle被调用");
        HttpSession session = request.getSession();
        String name = (String) session.getAttribute("name");
        if("dalao".equals(name)){
    
    
            System.out.println("--------------------当前浏览器存在session");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("afterCompletion被调用");
        long startTime = (Long) request.getAttribute("startTime");
        System.out.println("--------------------请求耗时:" + (System.currentTimeMillis() - startTime));
    }
}

监听器

监听器介绍

▶▶▶ServletContextListener:用来监听ServletContext属性的操作,比如新增、修改、删除。 · 
▶▶▶HttpSessionListener:用来监听Web应用中的Session对象,通常用于统计在线情况。 · 
▶▶▶ServletRequestListener:用来监听Request对象的属性操作。

使用监听器

使用监听器的话,只需要在类中实现对应功能的监听器对象,如本文使用的HttpSessionListener。下面以监听Session信息为例统计在线人数。新建一个MyHttpSessionListener类,实现HttpSessionListener类,在类中定义一个全局变量online,当创建Session时,online的数量加1;当销毁Session时,online的数量减1
MyHttpSessionListener完整内容:


public class MyHttpSessionListener implements HttpSessionListener {
    
    

    public volatile static int online = 0;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
    
    
        System.out.println("sessionCreated被调用");
        online ++;
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
    
    
        System.out.println("sessionDestroyed被调用");
        online --;
    }
}

修改启动类

过滤器、监听器和拦截器我们已经创建好了,但是还不能引用。接下来我们修改Spring Boot启动类,在类中通过注入Bean的方式引用三者。启动类完整内容如代码清单11-16所示(也可以使用其他方法引用,比如创建一个配置类统一管理)。


@SpringBootApplication
public class Chapter114Application implements WebMvcConfigurer {
    
    

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


	@Autowired
	private MyInterceptor myInterceptor;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
    
    
		registry.addInterceptor(myInterceptor);
	}


	@Bean
	public FilterRegistrationBean filterRegist() {
    
    
		FilterRegistrationBean frBean = new FilterRegistrationBean();
		frBean.setFilter(new MyFilter());
		frBean.addUrlPatterns("/*");
		return frBean;
	}

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

测试:
在这里插入图片描述
换一个浏览器:
在这里插入图片描述
在这里插入图片描述
在浏览器输入非online addsession removesession等的其他地址,会自动跳转到online:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41358574/article/details/121029519
今日推荐