Filter中抛出异常的处理

49 篇文章 1 订阅

Feile

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerExceptionResolver;

import com.wangyong.bee.common.exception.BizException;
import com.wangyong.bee.common.exception.ErrorContext;
import com.wangyong.license.api.error.LicenseServiceErrorCode;
import com.wangyong.license.api.service.MicroCloudLicenseService;
import com.mowangyongredian.license.cache.LicenseConfLocalCache;
import com.wangyong.license.listener.LicenseConfListener;
import com.wangyong.license.model.CacheNode;

@Order(3)
@WebFilter(initParams = { @WebInitParam(name = "nofilter", value = "/one,/two") })
@Configuration
public class LicenseFilterConfig implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(LicenseInterceptor.class);

    /**
     * 不过滤的资源
     */
    private String[] nofilter;

    private static List<String> filterPathPatterns = new ArrayList<>();

    @Autowired
    private volatile ApplicationContext applicationContext;

    @Autowired
    private MicroCloudLicenseService licenseService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //将不过滤的资源存入数组中
        String nofilterString = filterConfig.getInitParameter("nofilter");
        if (nofilterString != null && nofilterString.length() > 0) {
            nofilter = nofilterString.split(",");
        }

        System.out.println("Servlet init ... ");
        // 添加匹配的规则, /** 表示匹配所有规则,任意路径

        Collection<LicenseConfListener> licenseConfListeners = new LinkedList<>(this.applicationContext.getBeansOfType(LicenseConfListener.class).values());
        for (LicenseConfListener licenseConfListener : licenseConfListeners) {
            List<CacheNode> cacheNodes = licenseConfListener.registerUrlFilter();
            LicenseConfLocalCache.loadConf(cacheNodes);

            if (!CollectionUtils.isEmpty(cacheNodes)) {
                for (CacheNode cacheNode : cacheNodes) {
                    filterPathPatterns.add(cacheNode.getFilterUrl());
                }
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest  httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        BizException        exception          = doFilter(httpServletRequest);
        if (exception == null) {
            //调用下一个filter链
            chain.doFilter(servletRequest, response);
        }else {
            resolver.resolveException(httpServletRequest,httpServletResponse,null,exception);
        }

    }

    @Override
    public void destroy() {
        this.destroy();
    }

    /**
     *doFilter  判断路径是否不需要过滤
     */
    public BizException doFilter(HttpServletRequest request) {
        BizException bizException = null;
        String       requestURI   = request.getRequestURI();
        logger.info("handle url 是否需要验证 license. url:{}", requestURI);
        CacheNode cacheNode = LicenseConfLocalCache.localCache.get(requestURI);
        if (null != cacheNode) {
            logger.info("license 验证的 url 的权限. url:{}", requestURI);
            boolean serviceIsValid = licenseService.checkMircoServiceValid(cacheNode.getServiceNumber());
            BizAssert.isTrue(serviceIsValid,LicenseServiceErrorCode.ACCREDIT_OVERDUE_OR_NONE_ACCREDIT, LicenseServiceErrorCode.ACCREDIT_OVERDUE_OR_NONE_ACCREDIT.getMessage());
        }

        return bizException;
    }
}

Filter机制是基于Servlet的原理实现的,因此filter的执行策略是在执行Controller前执行的因此常见的全局异常处理机制@RestControllerAdvice、@ExceptionHandler(Exception.class)、是不生效的

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.wangyong.bee.tube.ResponseUtil;

@RestControllerAdvice
public class LicenseCommonExceptionHandler {

    protected static final Logger logger = LoggerFactory.getLogger(LicenseCommonExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public void handleException(Exception exception, HttpServletRequest request, HttpServletResponse response) {

        //异常需要处理的业务***
        ResponseUtil.handleException(exception, request, response);
        
    }

}

需要通过HandlerExceptionResolver的been进行处理

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerExceptionResolver;

import com.wangyong.bee.common.exception.BizException;
import com.wangyong.bee.common.exception.ErrorContext;
import com.wangyong.license.api.error.LicenseServiceErrorCode;
import com.wangyong.license.api.service.MicroCloudLicenseService;
import com.wangyong.license.cache.LicenseConfLocalCache;
import com.wangyong.license.listener.LicenseConfListener;
import com.wangyong.license.model.CacheNode;

@Order(3)
@WebFilter(initParams = { @WebInitParam(name = "nofilter", value = "/one,/two") })
@Configuration
public class LicenseFilterConfig implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(LicenseInterceptor.class);

    /**
     * 不过滤的资源
     */
    private String[] nofilter;

    private static List<String> filterPathPatterns = new ArrayList<>();

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Autowired
    private volatile ApplicationContext applicationContext;

    @Autowired
    private MicroCloudLicenseService licenseService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //将不过滤的资源存入数组中
        String nofilterString = filterConfig.getInitParameter("nofilter");
        if (nofilterString != null && nofilterString.length() > 0) {
            nofilter = nofilterString.split(",");
        }

        System.out.println("Servlet init ... ");
        // 添加匹配的规则, /** 表示匹配所有规则,任意路径

        Collection<LicenseConfListener> licenseConfListeners = new LinkedList<>(this.applicationContext.getBeansOfType(LicenseConfListener.class).values());
        for (LicenseConfListener licenseConfListener : licenseConfListeners) {
            List<CacheNode> cacheNodes = licenseConfListener.registerUrlFilter();
            LicenseConfLocalCache.loadConf(cacheNodes);

            if (!CollectionUtils.isEmpty(cacheNodes)) {
                for (CacheNode cacheNode : cacheNodes) {
                    filterPathPatterns.add(cacheNode.getFilterUrl());
                }
            }
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest  httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        BizException        exception          = doFilter(httpServletRequest);
        if (exception == null) {
            //调用下一个filter链
            chain.doFilter(servletRequest, response);
        }else {
            resolver.resolveException(httpServletRequest,httpServletResponse,null,exception);
        }

    }

    @Override
    public void destroy() {
        this.destroy();
    }

    /**
     *doFilter  判断路径是否不需要过滤
     */
    public BizException doFilter(HttpServletRequest request) {
        BizException bizException = null;
        String       requestURI   = request.getRequestURI();
        logger.info("handle url 是否需要验证 license. url:{}", requestURI);
        CacheNode cacheNode = LicenseConfLocalCache.localCache.get(requestURI);
        if (null != cacheNode) {
            logger.info("license 验证的 url 的权限. url:{}", requestURI);
            boolean serviceIsValid = licenseService.checkMircoServiceValid(cacheNode.getServiceNumber());
            if (!serviceIsValid) {
                bizException = new BizException();
                bizException.setErrorContext(new ErrorContext(LicenseServiceErrorCode.ACCREDIT_OVERDUE_OR_NONE_ACCREDIT, LicenseServiceErrorCode.ACCREDIT_OVERDUE_OR_NONE_ACCREDIT.getMessage()));
            }
        }

        return bizException;
    }
}
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
resolver.resolveException(httpServletRequest,httpServletResponse,null,exception);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值