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);