Java中Filter过滤器Interceptor拦截器的比较和登录验证入门案例

本文介绍了Java中的Filter过滤器和Interceptor拦截器。Filter是JavaWeb三大组件之一,可完成登录校验等通用操作;Interceptor是Spring框架提供的,用于动态拦截控制器方法。文中还阐述了二者实现接口、拦截范围的不同,并给出了实现方法及登录验证示例。
前言

Filter表示过滤器,是 JavaWeb三大组件(Servlet、Filter、Listener)之一。使用了过滤器之后,要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后,才可以访问对应的资源。过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等;拦截器

Interceptor拦截器 是Spring框架中提供的,用来动态拦截控制器方法的执行。是一种动态拦截方法调用的机制,类似于过滤器。

***实现的接口不同:Filter过滤器实现的是:Filter

                              Interceptor拦截器:HandlerInterceptor

***拦截范围不同:过滤器Filter会拦截所有的资源(包括静态资源),而Interceptor只会拦截Spring环境中的资源(controller)

1.Filter过滤器
 1.定义一个过滤器方法 实现 Filter类

 2.实现Filter中的方法

3. 三种方法的作用
@WebFilter(urlPatterns = "/*") //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
public class DemoFilter implements Filter {
    //初始化方法,web服务器启动,常见filter实例调用,只调用一次
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init....开启初始化");
    }
    //拦截请求,调用该方法,可以调用多次
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到了请求");
        filterChain.doFilter(servletRequest,servletResponse);//放行所有
        System.out.println("放行了");
    }
    //销毁方法,web服务器关闭时调用,只调用一次
    @Override
    public void destroy() {
        System.out.println("destroy...关闭了");
    }
}

4. 展示效果

 5.执行顺序问题

                                                                          图(1)

图(2)

图(3) 

 **过滤器的登录验证 (例)
@WebFilter(urlPatterns = "/*")
public class AuthFilter implements Filter {
    private static String signKey = "**********";私钥
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.获取url
        //获取url地址需要HttpServletRequest
        //HttpServletRequest是ServletRequest得子类, 我们直接强转
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //得到uri 获取url和uri效果是一样的 我们随便选择一个
        String uri = request.getRequestURI();
        //StringBuffer url = request.getRequestURL();
        //2.判断地址和登录的login是否包含  包含直接放行
        if (uri.contains("login")) {
            //相同就放行
            filterChain.doFilter(servletRequest, servletResponse);
            return;//重点 必须要返回
        }
        //3.获取请求头中的 token
        String token = request.getHeader("token");
        //4.如果存在就放行,不存在返回401报错
        if (!StringUtils.hasLength(token)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;//必须返回
        }
        //5.解析token         (解析不会的请移步 java会话技术详解)
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(signKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;//必须返回
        }
        //6.放行
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
2.Interceptor拦截器
 1.自定义拦截器必须实现HandlerInterceptor

 2.实现它的三个方法

 

3.拦截器入门案例 
@Component//放入Bean容器中
public class DemoInterceptor implements HandlerInterceptor {
    //目标资源方法执行之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("目标方法执行之前执行");
        return true;//表示放行
    }
    //目标资源方法执行之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        System.out.println("目标资源方法执行之后执行");
    }
    //视图渲染完毕之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        System.out.println("最后执行的方法");
    }
}

 将demo过滤器加入到WebConfiger

    @Autowired
    private DemoInterceptor demoInterceptor;
//    registry 该参数是spring mvc中的拦截器链
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(demoInterceptor).addPathPatterns("/**");// --/**表示拦截所有后端controller的请求
    }
4.拦截器在登录验证中的实例发挥 (例)
@Component
public class AuthInterceptor implements HandlerInterceptor {
    private static String signKey = "*********";//私钥
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        return HandlerInterceptor.super.preHandle(request, response, handler);
        //1.首先获取uri
//        String uri = request.getRequestURI();
//        if (uri.contains("/login")){
//            return true;
//        }
        //2.获取token
        String token = request.getHeader("token");
        //3.判断令牌是否存在,
        if(!StringUtils.hasLength(token)){
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        //4.解析token
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(signKey)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        return true;
    }
}
 5.在自定义拦截器中必须实现WebMvcConfiger方法

将AuthInterceptor拦截器添加到WebConfiger

同时excludePathPatterns("/login")是将/login放行 与AuthInterceptor中获取的URI二者选其一

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值