在javaweb开发中,过滤器Filter比较常用于类似登录的拦截等场景。但是,当过滤器的配置不当时就会把所有的请求都拦截,静态资源也会被拦截掉,导致静态页面加载不出来。
一般的解决方案是在过滤器代码中对所有的静态资源放行,但这样硬编码的方式特别不灵活,代码复用性也不高。下面说个更优雅点的方案。

一、解决方案

如果将静态资源放行的功能做成在web.xml中可以直接配置的话,就比较方便了。因此我们可以采用配置Filter的init-param的方式来配置那些资源不需要过滤器拦截,然后在过滤器Filter中的init方法去取这个配置的init-param。 具体的还是直接上代码吧。

二、代码

(1)web.xml中Filter的配置代码片段如下
这里的重点是配置了一个init-param
  <!--身份验证、登录、权限--><filter><filter-name>authorityFilter</filter-name><filter-class>com.hk.uc.client.filter.RestAuthorizeFilter</filter-class><init-param><!-- 配置不需要被登录过滤器拦截的链接,只支持配后缀、前缀 及全路径,多个配置用逗号分隔 --><param-name>excludedPaths</param-name><param-value>/pages/*,*.html,*.js,*.ico</param-value></init-param></filter><filter-mapping><filter-name>authorityFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
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的代码如下
代码解释如下:
  • 首先我声明了excludedPaths用来接收web.xml中配置的init-param
  • 在init()方法中把init-param的值赋值给excludedPaths
  • 写一个方法用来判断是否是直接放行的请求,这里写了isFilterExcludeRequest()这个方法
  • 在doFilter()这个方法中,先调用isFilterExcludeRequest()这个方法,判断是否应该直接放行。如果不是直接放行才走我们的逻辑代码
import java.io.IOException;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kangxiinfo.framework.common.util.StringUtils;/*** 身份认证过滤器* @author ZENG.XIAO.YAN* @time   2018-10-19 14:07:44* @version  v1.0*/
public class RestAuthorizeFilter implements Filter {/*** 不需要被过滤器拦截的页面 ,主要用于静态资源的放行* 在web.xml中配置filter的init-param*/    private String excludedPaths; private String [] excludedPathArray;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化时读取web.xml中配置的init-paramexcludedPaths = filterConfig.getInitParameter("excludedPaths");if(!StringUtils.isNullOrBlank(excludedPaths)){excludedPathArray = excludedPaths.split(",");}}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 判断是否是直接放行的请求if (!isFilterExcludeRequest(request)) {// TODO 这里写你的过滤器处理逻辑}filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {// TODO Auto-generated method stub}/*** 判断是否是 过滤器直接放行的请求* <br/>主要用于静态资源的放行* @param url* @return*/private boolean isFilterExcludeRequest(HttpServletRequest request) {if(null != excludedPathArray && excludedPathArray.length > 0) {String url = request.getRequestURI();for (String ecludedUrl : excludedPathArray) {if (ecludedUrl.startsWith("*.")) {// 如果配置的是后缀匹配, 则把前面的*号干掉,然后用endWith来判断if(url.endsWith(ecludedUrl.substring(1))){return true;}} else if (ecludedUrl.endsWith("/*")) {if(!ecludedUrl.startsWith("/")) {// 前缀匹配,必须要是/开头ecludedUrl = "/" + ecludedUrl;}// 如果配置是前缀匹配, 则把最后的*号干掉,然后startWith来判断String prffixStr = request.getContextPath() + ecludedUrl.substring(0, ecludedUrl.length() - 1);if(url.startsWith(prffixStr)) {return true;}} else {// 如果不是前缀匹配也不是后缀匹配,那就是全路径匹配if(!ecludedUrl.startsWith("/")) {// 全路径匹配,也必须要是/开头ecludedUrl = "/" + ecludedUrl;}String targetUrl = request.getContextPath() + ecludedUrl;if(url.equals(targetUrl)) {return true;}}}}return false;}
}
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

三、小结

(1)通过解决这个问题,学会了filter的init-param该怎么玩
(2)后续可以直接复用这个代码了,静态资源的放行直接在web.xml中配置。

转载于:https://www.cnblogs.com/zeng1994/p/638bcf0b5278b3658da9435d84058db8.html

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

  1. springboot 整合 Servlet、Filter、Listener、访问静态资源

    springboot 整合 Servlet.Filter.Listener.访问静态资源 1.引入pom.xml依赖 <dependency><groupId>org.spri ...

  2. 使用 imitator 实现前后端分离开发中的数据模拟与静态资源映射

    imitator 一个简单易用的 nodejs 服务器, 主要用于模拟 HTTP 接口数据, 请求代理与转发 . 使用imitator,可以解决前后端分离开发中的痛点之一:数据模拟,也可以作为代理服务 ...

  3. springboot开发中resources下的静态资源css,html,js等实时生效(热更新)

    在springboot项目开发过程中,遇到在resources文件下的静态资源的修改,必须要重启项目才能生效问题,做如下操作.\ 1.修改settings 2.修改registry(快捷键 Shift ...

  4. 自定义filter中配置不被过滤的资源

    1.web.xml中配置 <!-- token filter--><filter><filter-name>tokenFilter</filter-name& ...

  5. 5.15 vs2019 静态编译_Go Web 开发如何优雅的包含静态资源文件?

    点击上方蓝色"Go语言中文网"关注我们,领全套Go资料,每天学习 Go 语言 静态文件,也有人叫资产或资源,是一些被程序使用.没有代码的文件.在 Go 中,这类文件就是非 .go ...

  6. Spring MVC中静态资源加载

    问题:MVC 静态资源加载,包括 js.css.image加载不出来 由于web.xml中dispatcherServlet中 url-pattern 使用 / 拦截所有访问,而导致静态资源也交给了D ...

  7. 解决springmvc中添加了静态资源访问路径之后就访问不到Controller路径的问题

    访问不到Controller,也访问不到controller路径. Controller代码: /*** Created by 李柏霖* 2020/10/19 17:35*/package com.l ...

  8. SpringSecurity权限管理框架系列(七)-SpringSecurity自定义配置类中自定义Filter的使用详解

    1.Filter请求过滤器 filter请求过滤器可以帮助我们进行HttpServletRequest请求和HttpServletResponse响应的过滤 在自定义的Filter过滤器中我们可以对我 ...

  9. Spring Security 入门(四):自定义-Filter

    前文导读 - Spring Security入门(一):登录与退出 - Spring Security入门(二):基于数据库验证 - Spring Security入门(三):密码加密 本文解决问题 ...

  10. 【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener

    =================6.SpringBoot拦截器实战和 Servlet3.0自定义Filter.Listener ============ 1.深入SpringBoot2.x过滤器Fi ...

最新文章

  1. LLVM编译器基础架构与DragonEgg示例
  2. Struts2+spring+jdbc 以xml配置形式整合
  3. Java跌落神坛,Python继续夺冠....凭啥?
  4. ZooKeeper 的典型应用场景
  5. 动态开辟指定数量的线程来查找动态开辟的数组中的1000000数据中的值
  6. 终于有人把卷积神经网络(CNN)讲明白了
  7. Angular企业级开发(3)-Angular MVC实现
  8. Linux下的超级终端minicom与XGCom
  9. 如何远程调试zookeeper集群
  10. 【FPGA入门一】一个简单的LED流水灯
  11. java 找不到或无法加载主类 test_JAVA报找不到或无法加载主类的错误
  12. java 文字串叠字检查_Java 正则表达式详细实例解析
  13. matlab计算加减乘除,matlab计算矩阵的加减乘除以及逆
  14. kubespray安装高可用k8s集群
  15. 三电极体系电化学传感器
  16. Python字符串| min()
  17. C#报表开发工具ReportViewer vs Stimulsoft Reports.Net
  18. 鼠标在用了一段之后偶然发现以给特别慢的速度移动鼠标,会在移动到可点击的选项按钮附近明显的卡住问题。
  19. acr38u PHP调用,ACR38智能卡读写器驱动下载
  20. 在 DataFrame 多列数据中模糊查找匹配数据

热门文章

  1. 智芯传感ZXP0电容式大气压力传感器 拓展多领域创新应用
  2. Python爬虫实战之爬取链家广州房价_03存储
  3. web新手之使用easyAR实现WebAR
  4. 【软件测试管理与实践-软件质量】
  5. 苹果sf字体_全网首发丨iOS13越狱系统字体分析+iOS13新字体分享
  6. 吊打本地搜索神器everthing,最快 最强的电脑本地搜索神器!
  7. 实验一、安卓开发环境基本配置实验
  8. Qt疑难杂症之编译QPA插件
  9. prometheus实战(一) 原理介绍
  10. PAT-Basic Level-1001 害死人不偿命的(3n+1)猜想;