SpringBoot学习笔记——filter和interceptor

Servlet API中提供了一个Filter接口,Filter接口在javax.servlet.Filter包下面。开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter

通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。

例如实现URL级别的权限访问控制、乱码问题过滤敏感词汇压缩响应信息等一些高级功能。

filter在开发中的常见应用:
        1.filter可以目标资源执行之前,进行权限检查,检查用户有无权限,如有权限则放行,如没有,则拒绝访问
        2.filter可以放行之前,对request和response进行预处理,从而实现一些全局性的设置。
        3.filter在放行之后,可以捕获到目标资源的输出,从而对输出作出类似于压缩这样的设置 

在filter中可以对request请求进行拦截,并对response进行修改

实现Filter接口的话,需要重写3个方法init,doFilter和destroy

public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    void destroy();
}

而实现 OncePerRequestFilter 接口只用重写1个方法,其和 Filter 的区别参考:OncePerRequestFilter的作用

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

    }
}

下面使用 OncePerRequestFilter 来实现一个java web token认证的功能

1. 定义 JwtAuthenticationFilter

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        Cookie[] cookies = request.getCookies();
        int len = cookies.length;
        for (int i = 0; i < len; i++) {
            Cookie cookie = cookies[i];
            if ("token".equals(cookie.getName())) {
                log.info("has token");
                break;
            }
            if (i == len - 1) {
                log.info("no token");
            }
        }

        filterChain.doFilter(request, response);
    }
}

2. 配置filter,使该filter生效

import com.example.demo.jwt.JwtAuthenticationFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<JwtAuthenticationFilter> jwtFilter() {
        FilterRegistrationBean<JwtAuthenticationFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new JwtAuthenticationFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(1);
        return registration;
    }
}

3.请求接口,cookie中没有携带token的话,将会打印出no token

 

 

使用interceptor实现认证,参考:后端接口幂等性校验(数据库唯一索引 + 自定义注解和拦截器的token校验)

1. 定义interceptor

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Slf4j
public class CheckTokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Cookie[] cookies = request.getCookies();
        int len = cookies.length;
        for (int i = 0; i < len; i++) {
            Cookie cookie = cookies[i];
            if ("token".equals(cookie.getName())) {
                log.info("has token");
                break;
            }
            if (i == len - 1) {
                log.info("no token");
            }
        }
        return true; // 是否放行
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}

2. 配置config

import com.example.demo.jwt.CheckTokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class LoginConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 加载check token interceptor
        registry.addInterceptor(new CheckTokenInterceptor())
                .addPathPatterns("/**");
//                .excludePathPatterns("/admin")
//                .excludePathPatterns("/admin/login");
    }
}

3.请求接口,cookie中没有携带token的话,将会打印出no token

 

 

filter,interceptor和aop的区别参考:过滤器、拦截器和AOP的分析与对比

posted @ 2016-03-28 19:38  tonglin0325  阅读(189)  评论(0编辑  收藏  举报