背景
每次登陆手机版的各大商城,点击购买的时候都会进行拦截有没有登陆过,若存在的鉴权在有效期或者已经登陆过了,就直接进入支付环节,若登陆信息不存在或失效则直接被要求重新登陆,其中这里面如果用户是没有登陆会被过滤器过滤,是否可能继续请求。
拦截过滤器模式是什么?
拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。
角色:
过滤器(Filter):过滤器在请求处理程序执行请求之前或之后,执行某些任务。
过滤器链(Filter Chain):过滤器链带有多个过滤器,并在 Target 上按照定义的顺序执行这些过滤器。
处理程序(Target ):请求处理程序;
过滤管理器(Filter Manager):过滤管理器管理过滤器和过滤器链。
客户端(Client):Client 是向 Target 对象发送请求的对象。
优点:
低耦合高内聚:通过过滤管理器统一内聚了过滤链,将所有的过滤器统一聚合在一起,而之间耦合度非常低;
复用性高:由于有过滤链,所以可以建立很多的不同链而链中的过滤器是一样的,可以提高过滤器复用性;
预处理:由于用户请求可以在未进入主程序就被拦截到,所有可以提前就预处理了该用户请求的信息;
缺点:
增加程序的复杂度,由于增加了非常多的过滤器会导致该程序复杂度变高;
拦截过滤器模式可以干嘛?
过滤器主要是用来过滤一些非法请求,设置一些请求的编码或格式,将请求中的rquest信息进行过滤或添加一些请求头信息,常用的是配置统一编码或者配置cors一些非法攻击等。
个人理解:
拦截过滤器就像你去坐地铁,首先要通过检查,符合才能进,不符合可能直接被拉走,然后进入地铁,要刷卡、扫码或投币,如果刚好手机没电了那不好意思用投币或刷卡吧,当进入后,会根据你乘的信息出站时统一收费。
拦截过滤器模式类图
实现代码
/**
* @Auther: csh
* @Date: 2020/7/3 15:13
* @Description:抽象过滤器(abstract filter)
*/
public interface IFilter {
public void execute(String request);
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:20
* @Description: 权限过滤器(filter)
*/
public class AuthorizationFilter implements IFilter {
@Override
public void execute(String request) {
if(request.contains("admin")){
System.out.println("进入管理后台");
}else{
System.out.println("没有权限");
}
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:21
* @Description:日志记录过滤器(filter)
*/
public class LogFitler implements IFilter {
@Override
public void execute(String request) {
System.out.println("日志记录:"+request);
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:30
* @Description:请求进行处理
*/
public class Target {
public void execute(String request){
String user = request.contains("admin")?"管理员":"用户";
System.out.println(user+"进行登陆");
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:31
* @Description:过滤链
*/
public class FilterChain {
private List<IFilter> filters = new ArrayList <IFilter>();
private Target target;
public void addFilter(IFilter filter){
filters.add(filter);
}
public void excute(String request){
for (IFilter filter : filters) {
filter.execute(request);
}
target.execute(request);
}
public void setTarget(Target target){
this.target = target;
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:37
* @Description:过滤管理器
*/
public class FilterManager {
FilterChain filterChain;
public FilterManager(Target target){
filterChain = new FilterChain();
filterChain.setTarget(target);
}
public void setFilter(IFilter filter) {
filterChain.addFilter(filter);
}
public void filterRequest(String request){
filterChain.excute(request);
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:40
* @Description:用户
*/
public class Client {
FilterManager filterManager;
public void setFilterManager(FilterManager filterManager){
this.filterManager = filterManager;
}
public void sendRequest(String request){
filterManager.filterRequest(request);
}
}
/**
* @Auther: csh
* @Date: 2020/7/3 15:41
* @Description:
*/
public class Test {
public static void main(String[] args) {
FilterManager filterManager = new FilterManager(new Target());
filterManager.setFilter(new AuthorizationFilter());
filterManager.setFilter(new LogFitler());
Client client = new Client();
client.setFilterManager(filterManager);
client.sendRequest("admin");
client.sendRequest("USER");
}
}
结果
进入管理后台
日志记录:admin
管理员进行登陆
没有权限
日志记录:USER
用户进行登陆
最后
拦截过滤器,其实过滤器是过滤器,拦截器是拦截器,在实际spring、springboot或其他框架中,过滤器主要用来过滤一些非法的用户请求或用户请求的时候在请求头中添加特定的定信息,而拦截器则通过过滤器传递过来的信息对用户进行拦截,然后再转发到相应的下一层。
过滤器场景使用:
在web.xml中
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Access-Control-Allow-Origin,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
参考文章:
https://www.cnblogs.com/syuf/p/6845406.html