如何在自定义Filter中优雅的实现静态资源放行

 在javaweb开发中,过滤器Filter比较常用于类似登录的拦截等场景。但是,当过滤器的配置不当时就会把所有的请求都拦截,静态资源也会被拦截掉,导致静态页面加载不出来。

一般的解决方案是在过滤器代码中对所有的静态资源放行,但这样硬编码的方式特别不灵活,代码复用性也不高。下面说个更优雅点的方案。
一、解决方案
如果将静态资源放行的功能做成在web.xml中可以直接配置的话,就比较方便了。因此我们可以采用配置Filter的init-param的方式来配置那些资源不需要过滤器拦截,然后在过滤器Filter中的init方法去取这个配置的init-param。 具体的还是直接上代码吧。
二、代码
(1)web.xml中Filter的配置代码片段如下
这里的重点是配置了一个init-param
1

2

3
authorityFilter
4
com.hk.uc.client.filter.RestAuthorizeFilter
5

6

7
excludedPaths
8
/pages/,.html,.js,.ico
9

10

11

12
authorityFilter
13
/*
14

(2)自定义Filter的代码如下
代码解释如下:
首先我声明了excludedPaths用来接收web.xml中配置的init-param
在init()方法中把init-param的值赋值给excludedPaths
写一个方法用来判断是否是直接放行的请求,这里写了isFilterExcludeRequest()这个方法
在doFilter()这个方法中,先调用isFilterExcludeRequest()这个方法,判断是否应该直接放行。如果不是直接放行才走我们的逻辑代码

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
*
主要用于静态资源的放行
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
三、小结
(1)通过解决这个问题,学会了filter的init-param该怎么玩
(2)后续可以直接复用这个代码了,静态资源的放行直接在web.xml中配置。

作者:zeng1994
出处:http://www.cnblogs.com/zeng1994/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值