如何在自定义Filter中优雅的实现静态资源放行
一、解决方案
二、代码
(1)web.xml中Filter的配置代码片段如下
<!--身份验证、登录、权限-->
<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>
<!--身份验证、登录、权限-->
<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>
(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;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化时读取web.xml中配置的init-param
excludedPaths = filterConfig.getInitParameter("excludedPaths");
if(!StringUtils.isNullOrBlank(excludedPaths)){
excludedPathArray = excludedPaths.split(",");
}
}
@Override
public 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);
}
@Override
public 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;
}
}
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;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化时读取web.xml中配置的init-param
excludedPaths = filterConfig.getInitParameter("excludedPaths");
if(!StringUtils.isNullOrBlank(excludedPaths)){
excludedPathArray = excludedPaths.split(",");
}
}
@Override
public 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);
}
@Override
public 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;
}
}
三、小结
(1)通过解决这个问题,学会了filter的init-param该怎么玩(2)后续可以直接复用这个代码了,静态资源的放行直接在web.xml中配置。
如何在自定义Filter中优雅的实现静态资源放行的更多相关文章
- springboot 项目中css js 等静态资源无法访问的问题
目录 问题场景 问题分析 问题解决 问题场景 今天在开发一个springboot 项目的时候突然发现 css js 等静态资源竟然都报404找不到,折腾了好久终于把问题都解决了,决定写篇博客,纪录总结 ...
- Spring Boot 中的静态资源到底要放在哪里?
当我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置,之前老有小伙伴在微信上问松哥Spring Boot 中的静态资源加载问题:"松哥,我的HTML页面好像没有样式?& ...
- Spring Boot中的静态资源文件
Spring Boot中的静态资源文件 1.SSM中的配置 2.Spring Boot 中的配置 2.1 整体规划 2.2 源码解读 2.3 自定义配置 2.3.1 application.prope ...
- 在Salesforce中使用静态资源
静态资源 静态资源是Salesforce中默认的一种数据类型,用户可以上传各种文件,比如zip文件.jpg文件.css文件.图像文件等. 在Visualforce页面.Lightning框架的开发过程 ...
- DirectX:在graph自动连线中加入自定义filter(graph中遍历filter)
为客户提供的视频播放的filter的测试程序中,采用正向手动连接的方式(http://blog.csdn.net/mao0514/article/details/40535791),由于不同的视频压缩 ...
- Python中自定义filter用法
django中新建项目,在项目中新建app,自定义filter一般放到app中.结构目录如下: 1.先在APP中新建一个templatetags的django文件夹,文件夹中新建一个filter的py ...
- Asp.net mvc自定义Filter简单使用
自定义Filter的基本思路是继承基类ActionFilterAttribute,并根据实际需要重写OnActionExecuting,OnActionExecuted,OnResultExecuti ...
- Jinja2模版语言自定义filter的使用
Jinja2模版语言,自带有一些filter,能够在前端的模版中控制数据按照相应的方式显示.比如以下两种filter,分别能在前端控制数字的近似精度显示和根据字符串长度补齐: round(value, ...
- HBase笔记--自定义filter
自定义filter需要继承的类:FilterBase 类里面的方法调用顺序 方法名 作用 1 boolean filterRowKey(Cell cell) 根据row key过滤row.如果需要 ...
随机推荐
- Linux swappiness参数设置与内存交换
swappiness参数设置与内存交换 by:授客 QQ:1033553122 简介 swappiness,Linux内核参数,控制换出运行时内存的相对权重.swappiness参数值可设置范围在0到 ...
- Ubuntu下解压缩文件
记录Ubuntu下各种压缩和解压方式: .tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)—————— ...
- 深入理解Java虚拟机06--虚拟机字节码执行引擎
一.前言 物理机的执行引擎是直接在物理硬件如CPU.操作系统.指令集上运行的,但是对于虚拟机来讲,他的执行引擎由自己实现. 执行引擎有统一的外观(Java虚拟机规范),不同类型的虚拟机都遵循了这一规范 ...
- odoo11 model+Recordset 基础未完待续
Model 一个模型代表了一个业务对象 本质上是一个类,包含了同django flask一样的数据字段 所有定义在模型中的方法都可以被模型本身的直接调用 现在编程范式有所改变,不应该直接访问模型,而是 ...
- [20190219]那个更快(11g).txt
[20190219]那个更快(11g).txt --//前几天测试11g Query Result Cache RC Latches时,链接http://blog.itpub.net/267265/v ...
- mssql 一次向表中插入多条数据的方法分享 (转自:http://www.maomao365.com/?p=6058)
转自:http://www.maomao365.com/?p=6058) <span style="font-size:16px;font-weight:bold;"> ...
- Cs231n课堂内容记录-Lecture 3 最优化
Lecture 4 最优化 课程内容记录: (上)https://zhuanlan.zhihu.com/p/21360434?refer=intelligentunit (下)https://zhua ...
- JavaScript -- 时光流逝(八):js中的事件Event的使用
JavaScript -- 知识点回顾篇(八):js中的事件Event的使用 事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行. (1) onabort : onabort 事件会在图像 ...
- 聚类——K-means
聚类——认识K-means算法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 一.聚类与分类 聚类: 无监督学习.聚类是在预先不知道欲划分类的情况下, ...
- JDK动态代理和cglib代理详解
JDK动态代理 先做一下简单的描述,通过代理之后返回的对象已并非原类所new出来的对象,而是代理对象.JDK的动态代理是基于接口的,也就是说,被代理类必须实现一个或多个接口.主要原因是JDK的代理原理 ...