过滤器(Filter)和拦截器(Interceptor)学习笔记

1.过滤器

1.1过滤器的概述

  • 概念:Filter 过滤器,是JavaWeb三大组件(Servlet、Filter、Listener)之一;
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能;
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

 

1.2过滤器的使用

  1. 定义Filter:定义一个类,实现 Filter 接口,并重写其所有方法。
  2. 配置FilterFilter类上加 @WebFilter 注解,配置拦截资源的路径。引导类(启动类)上加 @ServletComponentScan 开启Servlet组件支持
@WebFilter(urlPatterns="/*")//拦截的请求路径
public class DemoFilter implements Filter {
    @Override
    //初始化方法,Web服务器启动,创建过滤器时调用,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    //拦截请求时调用,可调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("放行前操作");
        filterChain.doFilter(servletRequest,servletResponse);//放行
        System.out.println("放行后操作");
    }

    @Override
    //销毁方法,服务器关闭时调用,只调用一次
    public void destroy() {
        Filter.super.destroy();
    }
}
  •  Filter 可以根据需求,配置不同的拦截资源路径

 注:如果存在多个拦截器,会根据拦截器的类名首字母排序依次先后执行,如A先于B;

1.3过滤器的登录案例

        过滤器部分:


@Slf4j
//@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            chain.doFilter(request,response);
            return;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        chain.doFilter(request, response);

    }
}

        JWT令牌部分: 

public class JwtUtils {

    private static String signKey = "youzhifan";
    private static Long expire = 43200000L;

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }
}

2.拦截器

2.1 拦截器的概述

  • 概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
  • 作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

 2.2 拦截器的使用

  1. 定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {

    @Override//目标资源方法执行前执行,返回true:放行 返回false:不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override//目标资源方法执行后执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override//视图渲染完毕后执行,最后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
  1. 注册拦截器。
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

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

 addPathPatterns:需要拦截哪些资源;

 excludePathPatterns:不需要拦截哪些资源;

2.3拦截器的登录案例

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        return true;
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }

    @Override //视图渲染完毕后运行, 最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

3.拦截器与过滤器的区别 

  •  接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
  • 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
  • 关于面试中涉及到的二者区别问题

 4.全局异常处理器

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)//捕获所有异常
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("对不起,操作失败,请联系管理员");
    }

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
filter过滤器拦截器是Web开发中常用的两种组件,它们在请求处理过程中起到了类似于"中间件"的作用,用于对请求进行处理和拦截。 Filter过滤器是Servlet规范中定义的一种组件,它可以对请求进行预处理和后处理。Filter可以拦截特定的URL请求,对请求进行处理,并将请求传递给下一个过滤器或Servlet。Filter可以用于对请求进行身份验证、日志记录、编码换、资源过滤等等操作。一个应用可以配置多个Filter,它们按照配置的顺序依次执行。 拦截器是在Spring框架中使用的一种组件,它也可以对请求进行预处理和后处理。拦截器的使用更加灵活,可以对请求进行更加细粒度的控制。拦截器可以拦截Controller方法的调用,在方法执行前后做一些处理,例如身份验证、日志记录、性能监控等。一个应用可以配置多个拦截器,它们按照配置的顺序依次执行。 在使用上,filterinterceptor有一些区别: - Filter是基于Servlet规范的,而Interceptor是Spring框架提供的; - Filter可以对所有的请求进行拦截,而Interceptor可以对Controller方法进行拦截; - Filter只能通过web.xml或注解进行配置,而Interceptor可以通过Java代码进行配置; - Interceptor可以访问Spring的上下文,而Filter不能。 总结来说,filterinterceptor都可以用于对请求进行处理和拦截,但是它们的具体实现和使用方式有一些差异。在使用时,可以根据具体需求选择适合的组件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值