工作记录:自定义Filter实现功能

本文介绍了如何在Servlet中使用自定义Filter来简化过滤器的实现过程。通过创建一个抽象类AbstractFilter实现Filter接口,并提供filtering抽象方法供子类实现过滤逻辑。此外,还定义了AbstractRequestFilter子类,增加了白名单功能,以便更方便地创建和管理过滤器。
摘要由CSDN通过智能技术生成

在Servlet中,可以通过实现Filter接口的方式对请求添加过滤器。Filter接口有如下几个方法:

package javax.servlet;

import java.io.IOException;

public interface Filter {


    public void init(FilterConfig filterConfig) throws ServletException;
   

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException;


    public void destroy();
}

对于init方法和destroy方法,分别会在Filter创建和销毁的时候会被调用,也就是对于整个Filter生命周期,两个方法只会被调用一次。当我们通过实现Filter接口来自定义过滤器时,如果直接实现Filetr接口,要实现大量的init和destroy方法,这也许不是我们需要的。所以,为了简化实现,可抽象出如下的工具类:

(1)定义一个抽象类AbstractFilter,直接实现Filter接口,并提供一个filtering抽象方法由子类实现具体的过滤逻辑:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *
 * 自定义Filter模板类
 *
 * 包访问权限为default,同一个包下面的类可以访问
 *
 * @author javaerui
 * @Description:
 * @date 2020/12/28
 */
abstract class AbstractFilter implements Filter {

    /**
     * 此方法时继承自Filter接口的,所以,每个Filter实现类都会调用此方法
     * 但是可以在重写的doFilter方法中,添加逻辑,控制不一定都要调用filtering方法
     *
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        doFilter((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse, filterChain);
    }

    /**
     * 子类可以通过重写此方法来调整逻辑
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException{
        filtering(request, response, filterChain);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // do something
    }

    @Override
    public void destroy() {
        // do something
    }

    /**
     * 具体的过滤器去实现此方法,用来实现具体的过滤逻辑
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    protected abstract void filtering(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException;

}

(2)定义AbstractRequestFilter,继承AbstractFilter,重写了doFilter方法,添加白名单功能。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @author javaerui
 * @Description:
 * @date 2020/12/28
 */
public abstract class AbstractRequestFilter extends AbstractFilter{

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRequestFilter.class);


    /**
     * 定义白名单,直接放行的请求url
     */
    private static final String[] whiteList = {"/ehr/corp/init", "/client", "/account/signin"};

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        if (skipFiltering(request)) {
            filterChain.doFilter(request, response);
            return;
        }
        filtering(request, response, filterChain);
    }

    /**
     * 是否跳过执行filtering方法
     * 处理给第三方提供的接口,无需执行其他的过滤器了
     * 子类可重写此方法来控制是否过滤
     * @param request
     * @return true,跳过执行filtering方法,否则,执行filtering
     */
    protected boolean skipFiltering(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        for (String whiteURI : whiteList) {
            if (requestURI.startsWith(whiteURI)) {
                return true;
            }
        }
        return false;
    }

}

(3)自定义过滤器,通过继承AbstractRequestFilter,实现filtering方法来完成过滤逻辑:

import com.google.common.util.concurrent.RateLimiter;

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

/**
 * 限流过滤器
 */
public class AccessFilter extends AbstractRequestFilter {

   private static final RateLimiter rateLimiter = RateLimiter.create(1000);

   @Override
   protected void filtering(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

      if (rateLimiter.tryAcquire(1)) {
         filterChain.doFilter(request, response);
      } else {
         // 拦截住当前请求
         ...
      }
   }

   /**
    * 重写AbstractRequestFilter中的方法,永远返回false,表示不放过任何的请求URL
    * @param request
    * @return
    */
   @Override
   protected boolean skipFiltering(HttpServletRequest request) {
      return false;
   }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值