博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springBoot的过滤器,监听器,拦截器
阅读量:4031 次
发布时间:2019-05-24

本文共 11134 字,大约阅读时间需要 37 分钟。

概述

  在开发中,我们经常要考虑一些问题,对敏感词进行过滤,用户是否已经登录,是否需要对他的请求进行拦截,或者领导问现在在线人数有多少人?我们如何实现这些功能哪

 @WebFilter

package com.xmlxy.firstspringbootproject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import java.io.IOException;@WebFilter(filterName = "customFilter",urlPatterns = "/*")public class CustomFilter implements Filter {    private static final Logger log = LoggerFactory.getLogger(CustomFilter.class);    @Override    public void init(FilterConfig filterConfig) throws ServletException {        log.info("===========拦截器初始化==========");    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        servletRequest.setCharacterEncoding("utf-8");        servletResponse.setCharacterEncoding("utf-8");        log.info("doFilter请求处理");    }    @Override    public void destroy() {        log.info("fifter销毁");    }}

在application类中添加@ServletComponentScan注解

package com;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;import org.springframework.context.annotation.PropertySource;@SpringBootApplication@ServletComponentScan@PropertySource(value = "classpath:jdbc.properties",encoding = "utf-8")public class FirstSpringbootProjectApplication {    public static void main(String[] args) {        SpringApplication.run(FirstSpringbootProjectApplication.class, args);    }}

运行结果

(笔误,应该是过滤器初始化)过滤器已经生效,但若有多个过滤器,无法指定执行顺序,我们可以通过Java类的名称,从A-L,按顺序执行。但这种方式毕竟不大靠谱,所以,有第二种写法,它提供setOrder函数,为filter设置排序值。

package com.xmlxy.service;import com.xmlxy.firstspringbootproject.CustomFilter;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class WebFilterConfig{    @Bean    public FilterRegistrationBean someFilterRegistration1()    {        FilterRegistrationBean registration = new FilterRegistrationBean<>();        System.out.println("我执行了。。。。。。。");        registration.setFilter(new CustomFilter());        registration.addUrlPatterns("/*");
     registration.setOrder(1);
     return registration; } }

我们尝试写个demo,验证一下过滤器是否执行。

用户登录对象

User.java

package com.xmlxy.bean;import lombok.Data;import org.springframework.stereotype.Component;@Data@Componentpublic class User {    private String user;    private String pwd;}

登录控制

LoginController.java

package com.xmlxy.firstspringbootproject;import com.xmlxy.bean.User;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;@RestControllerpublic class LoginController {    @RequestMapping(value = "login",method = RequestMethod.GET)    public String login(HttpServletRequest request)    {        String user = request.getParameter("user");        String pwd = request.getParameter("pwd");        HttpSession session = request.getSession();        if ("admin".equals(user) && "admin".equals(pwd))        {            User user1 = new User();            user1.setUser(user);            user1.setPwd(pwd);            session.setAttribute("user",user1);            return "登录成功";        }        return "密码错误,登录失败";    }
  @RequestMapping(value = "test",method = RequestMethod.GET)  public String test()  {      return "test接口";  }
}

过滤器

CustomFilter.java

package com.xmlxy.firstspringbootproject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;//@WebFilter(filterName = "customFilter",urlPatterns = "/*")public class CustomFilter implements Filter {    private static final Logger log = LoggerFactory.getLogger(CustomFilter.class);    String includes[] = {"/login","register"};    @Override    public void init(FilterConfig filterConfig) throws ServletException {        log.info("===========过滤器初始化==========");    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException    {        HttpServletRequest request = (HttpServletRequest) servletRequest;        HttpServletResponse response = (HttpServletResponse) servletResponse;        servletRequest.setCharacterEncoding("utf-8");        servletResponse.setCharacterEncoding("utf-8");        HttpSession session = request.getSession(false);        String uri = request.getRequestURI();        boolean flag = isNeedFilter(uri);        if (!flag)        {            filterChain.doFilter(servletRequest,servletResponse);            System.err.printf("登录成功");        }else {            if (session != null && session.getAttribute("user") != null)            {                filterChain.doFilter(servletRequest,servletResponse);            }else {                System.err.printf("暂时未登录");            }        }        log.info("doFilter请求处理");    }    public boolean isNeedFilter(String uri)    {        for (String include:includes)        {            if (include.equals(uri))            {                return false;            }        }        return true;    }    @Override    public void destroy() {        log.info("fifter销毁");    }}

过滤器配置

WebFilterConfig

package com.xmlxy.service;import com.xmlxy.firstspringbootproject.CustomFilter;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class WebFilterConfig{    @Bean    public FilterRegistrationBean someFilterRegistration1()    {        FilterRegistrationBean registration = new FilterRegistrationBean<>();        System.out.println("我执行了。。。。。。。");        registration.setFilter(new CustomFilter());        registration.addUrlPatterns("/*");        return registration;    }}

 运行测试。。访问 127.0.0.1/test  控制台

访问  http://127.0.0.1:8080/login?user=admin&pwd=admin,可以看到登录成功

在次访问 127.0.0.1/test 页面显示

所以,我们的过滤器成功过滤未登录的用户

监听器

正在你为自己会了过滤用户自鸣得意时,你的组长过来了,小明,你看下我们平台的在线用户有多少人。如果不知道监听器童鞋,是否会在登录接口处每次登录成功都+1,然而这种统计结果是不准确的,因为用户如果反复登录退出,那这个在值就远远大于实际值,最后就面临着,加班在加班的悲惨下场。

CustomLister.java

package com.xmlxy.firstspringbootproject;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;@WebFilterpublic class CustomLister implements HttpSessionListener{    public static int online = 0;    @Override    public void sessionCreated(HttpSessionEvent sessionEvent)    {        System.out.println("创建session,统计在线人数");        online ++;    }    @Override    public void sessionDestroyed(HttpSessionEvent sessionEvent)    {        System.out.println("session已经销毁");    }}

配置监听器配置,在刚才的WebFilterConfig.java添加

@Bean    public ServletListenerRegistrationBean listenerRegistrationBean()    {        ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();        srb.setListener(new CustomLister());        System.out.println("");        return srb;    }

添加一个访问在线人数的接口

@RequestMapping(value = "onLinePerson",method = RequestMethod.GET)    public String onLinePerson()    {        StringBuffer stringBuffer = new StringBuffer("");        stringBuffer.append(" 在线人数 ");        stringBuffer.append(CustomLister.online);        stringBuffer.append(" 个人 ");        return stringBuffer.toString();    }

访问127.0.0.1/onLinePerson,发现被拦截器拦截了,我们先登录。在查看接口

换个浏览器,调用下login接口,在查看

拦截器

拦截器,个人理解,在web上有些像是过滤器的补充,它能更精确的控制拦截哪些函数或者字段,在拦截之前或之后做一些操作。我们现在做一个敏感词的拦截,其实这个操作放在过滤器操作也是可以的,但lz因为刚才把拦截用户的操作放在过滤器了,在大规模更改,lz觉得没必要,因为都是大同小异。

CustomInterceptor.java

package com.xmlxy.firstspringbootproject;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.PrintWriter;public class CustomInterceptor implements HandlerInterceptor{    private static final Logger log = LoggerFactory.getLogger(CustomInterceptor.class);    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {        log.info("=======拦截器被调用=====");        String url = request.getRequestURI();        if (url != null && url.indexOf("seqing") != -1)        {            PrintWriter printWriter = response.getWriter();            printWriter.write("ming gan ci");            return false;        }        log.info("返回false 则中断请求");        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)    {        log.info("请求后调用");    }    @Override    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception e)    {        log.info("视图渲染完回调");    }}

配置拦截

package com.xmlxy.service;import com.xmlxy.firstspringbootproject.CustomFilter;import com.xmlxy.firstspringbootproject.CustomInterceptor;import com.xmlxy.firstspringbootproject.CustomLister;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class WebFilterConfig implements WebMvcConfigurer{    @Bean    public FilterRegistrationBean someFilterRegistration1()    {        FilterRegistrationBean registration = new FilterRegistrationBean<>();        System.out.println("我执行了。。。。。。。");        registration.setFilter(new CustomFilter());        registration.addUrlPatterns("/*");        return registration;    }    @Bean    public ServletListenerRegistrationBean listenerRegistrationBean()    {        ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean();        srb.setListener(new CustomLister());        return srb;    }    @Override    public void addInterceptors(InterceptorRegistry registry)    {        /*拦截规则*/        registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/*");    }}

现在测试访问127.0.0.1/seqing,被过滤,要求先登录。我们调用登录接口后,再次调用,发现被拦截了

看下日志调用,可以发现,拦截器是在访问接口前被调用的

过滤器,拦截器区别

这里主要说下拦截器和过滤器的区别和使用场景,通过demo可以发现,它们都能实现权限的检查,日志记录这些功能,主要说下它们的区别

  1. 过滤器和拦截器触发的时机是不同的,在进入servlet之前,过滤器就进行预处理了。而拦截器是在调用Controller之前才触发执行,过滤器的范围较广,对所有的请求都起作用,而拦截起只 对action起作用

  2.拦截器可以获取IOC容器的各个bean,而过滤器就不行。因为拦截器是spring提供管理的,也因此拦截器可以使用spring的任何资源。

  3.拦截器是利用Java反射机制实现,过滤器是函数的回调。因此实现方式是不同的。

三者使用场景

  监听器常用统计在线用户,统计网站的访问量,记录用户的访问路径

  过滤器:过滤敏感词,权限访问控制

  拦截器:权限验证,判断用户是否登录等

转载地址:http://ykgbi.baihongyu.com/

你可能感兴趣的文章
Spring Cloud微服务架构在互联网中应用
查看>>
gradle+maven+springboot实战
查看>>
uWSGI使用详解
查看>>
如何在ubuntu上卸载Jenkins
查看>>
Oracle数据库导入导出,exp/imp expdp/impdp
查看>>
Android开发中对应的三种照片的尺寸
查看>>
注册DLL、OCX的方法
查看>>
Android Theme即样式 简介
查看>>
ArcEngine ICoommand和ITool 的区别
查看>>
MyEclipse常用快捷键(逐步更新)
查看>>
Jquery之显示/隐藏
查看>>
jQuery之滑动
查看>>
远程桌面无法复制粘贴
查看>>
Eclipse+adt+sdk配置Android开发环境
查看>>
JS 字符/字母大小写切换
查看>>
JS页面间传值
查看>>
js类的使用
查看>>
Github创建、删除organization
查看>>
Github使用教程
查看>>
Git上传/下载项目到GitHub
查看>>