我瞎说两句吧。
首先呢,感觉你的需求广义上来讲也属于认证。参考Spring Security这种认证用过滤器比拦截器更适合。拦截器根据拦截的返回值true/false
来决定是否拦截,这样的机制决定了多个拦截器间没有办法直接传递信息。
但过滤器就不同了,过滤器之间靠过滤器链将多个过滤器连接在一起。我们可以在前置过滤器中对request或response进行装饰(当然可以把一些自定义的信息装饰进去了),然后再在后置过滤器中获取装饰过的request或reponse,再根据获取的值来进行一些逻辑处理。
比如我们在第一个过滤器的request新建一个authed请求头,默认值给false。然后第一个过滤器中再加入这样的逻辑:
- 获取 authed请求头,如果值为true,则直接放行。
- 如果值为false,则执行自己的认证逻辑。
2.1 如果逻辑通过,则设置authed为true
2.2 继续执行过滤链上的下一个过滤器。
如果说你的当前业务必须使用拦截器,建议尝试以下思路。
- 建立接口 InterceptorToken
- 为实际业务已存在的多个拦截器(下文中假设有两个,分别为A、B)建立接口 Xxxxoken,比如AInterceptorToken、BInterceptorToken,全部继承 InterceptorToken。
- 建立一个作用域为
当前请求
的Service
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
class public TokenContainer() {
List<InterceptorToken> tokens = new ArrayList<InterceptorToken>;
public void addToken(InterceptorToken token) {
// 在此还可以加入token类型是否存在的验证
this.tokens.add(token);
}
/**
* 判断token是否存在
* 没有实际运行,代码可能写的不对
**/
public boolean exists(class<InterceptorToken> token) {
// ....
}
}
再然后:
- 在第一个拦截器执行以前:获取请求信息,判断是否为
受信任节点发来的请求
或者其它你认为不需要再拦截在请求。 - 如果不想让A拦截,则addToken(AInterceptorToken)
- 如果同时不想让B拦截,再addToken(BInterceptorToken)
- 在A拦截器中增加:if(tokenContainer.exists(AInterceptorToken.class) then 不拦截
- 在B拦截器中增加:if(tokenContainer.exists(BInterceptorToken.class) then 不拦截
- 如果你需要一个让所有拦截器都不拦截的功能,则还可以建立一个GobalInterceptorToken,然后将A拦截器的中的代码改为:if(tokenContainer.exists(GobalInterceptorToken.class || AInterceptorToken.class) then 不拦截
希望对你有帮助。
另 Java旅途
的答案和我的答案可能都不是你想要的。但我们都是出于热心,我们可以接受你不回复、不评论。但如果回复或是评论我想我们还是希望能看到是更多的相互尊重与真诚的态度。毕竟在思否这个平台上,谁都没有帮助谁的业务。
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…