在javaweb开发中,过滤器Filter比较常用于类似登录的拦截等场景。但是,当过滤器的配置不当时就会把所有的请求都拦截,静态资源也会被拦截掉,导致静态页面加载不出来。 一般的解决方案是在过滤器代码中对所有的静态资源放行,但这样硬编码的方式特别不灵活,代码复用性也不高。下面说个更优雅点的方案。 一、解决方案 如果将静态资源放行的功能做成在web.xml中可以直接配置的话,就比较方便了。因此我们可以采用配置Filter的init-param的方式来配置那些资源不需要过滤器拦截,然后在过滤器Filter中的init方法去取这个配置的init-param。 具体的还是直接上代码吧。 二、代码(1)web.xml中Filter的配置代码片段如下 这里的重点是配置了一个init-param x 14 1 <!--身份验证、登录、权限--> 2 <filter> 3 <filter-name>authorityFilter</filter-name> 4 <filter-class>com.hk.uc.client.filter.RestAuthorizeFilter</filter-class> 5 <init-param> 6 <!-- 配置不需要被登录过滤器拦截的链接,只支持配后缀、前缀 及全路径,多个配置用逗号分隔 --> 7 <param-name>excludedPaths</param-name> 8 <param-value>/pages/*,*.html,*.js,*.ico</param-value> 9 </init-param> 10 </filter> 11 <filter-mapping> 12 <filter-name>authorityFilter</filter-name> 13 <url-pattern>/*</url-pattern> 14 </filter-mapping> (2)自定义Filter的代码如下 代码解释如下:
94 1 import java.io.IOException; 2 import javax.servlet.Filter; 3 import javax.servlet.FilterChain; 4 import javax.servlet.FilterConfig; 5 import javax.servlet.ServletException; 6 import javax.servlet.ServletRequest; 7 import javax.servlet.ServletResponse; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import com.kangxiinfo.framework.common.util.StringUtils; 11
12 /** 13 * 身份认证过滤器 14 * @author ZENG.XIAO.YAN 15 * @time 2018-10-19 14:07:44 16 * @version v1.0 17 */ 18 public class RestAuthorizeFilter implements Filter { 19 /** 20 * 不需要被过滤器拦截的页面 ,主要用于静态资源的放行 21 * 在web.xml中配置filter的init-param 22 */ 23 private String excludedPaths; 24 private String [] excludedPathArray; 25
26 @Override 27 public void init(FilterConfig filterConfig) throws ServletException { 28 // 初始化时读取web.xml中配置的init-param 29 excludedPaths = filterConfig.getInitParameter("excludedPaths"); 30 if(!StringUtils.isNullOrBlank(excludedPaths)){ 31 excludedPathArray = excludedPaths.split(","); 32 } 33 } 34 35 @Override 36 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 37 FilterChain filterChain) throws IOException, ServletException { 38 HttpServletRequest request = (HttpServletRequest) servletRequest; 39 HttpServletResponse response = (HttpServletResponse) servletResponse; 40 // 判断是否是直接放行的请求 41 if (!isFilterExcludeRequest(request)) { 42 // TODO 这里写你的过滤器处理逻辑 43 } 44 filterChain.doFilter(servletRequest, servletResponse); 45 } 46
47 48 @Override 49 public void destroy() { 50 // TODO Auto-generated method stub 51 } 52
53 /** 54 * 判断是否是 过滤器直接放行的请求 55 * <br/>主要用于静态资源的放行 56 * @param url 57 * @return 58 */ 59 private boolean isFilterExcludeRequest(HttpServletRequest request) { 60 if(null != excludedPathArray && excludedPathArray.length > 0) { 61 String url = request.getRequestURI(); 62 for (String ecludedUrl : excludedPathArray) { 63 if (ecludedUrl.startsWith("*.")) { 64 // 如果配置的是后缀匹配, 则把前面的*号干掉,然后用endWith来判断 65 if(url.endsWith(ecludedUrl.substring(1))){ 66 return true; 67 } 68 } else if (ecludedUrl.endsWith("/*")) { 69 if(!ecludedUrl.startsWith("/")) { 70 // 前缀匹配,必须要是/开头 71 ecludedUrl = "/" + ecludedUrl; 72 } 73 // 如果配置是前缀匹配, 则把最后的*号干掉,然后startWith来判断 74 String prffixStr = request.getContextPath() + ecludedUrl.substring(0, ecludedUrl.length() - 1); 75 if(url.startsWith(prffixStr)) { 76 return true; 77 } 78 } else { 79 // 如果不是前缀匹配也不是后缀匹配,那就是全路径匹配 80 if(!ecludedUrl.startsWith("/")) { 81 // 全路径匹配,也必须要是/开头 82 ecludedUrl = "/" + ecludedUrl; 83 } 84 String targetUrl = request.getContextPath() + ecludedUrl; 85 if(url.equals(targetUrl)) { 86 return true; 87 } 88 } 89 } 90 } 91 return false; 92 } 93 } 94
三、小结
|
|