花了很长时间来研究业务功能的实现,才发现原来自己的理解不够深刻,特地写出来以免后面人少走弯路:
业务场景:集成第三方认证和自身认证流程,使满足任何一项即可通过认证流程。
自我实现步骤(我这里是以老的web项目为例)
第一步:添加所需jar和web.xml配置(这里我是自建的filter)
<!-- 添加拦截器执行链自定义一环 -->
<filter>
<filter-name>testAuth</filter-name>
<filter-class>类的包路径</filter-class>
</filter>
<filter-mapping>
<filter-name>testAuth</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 添加拦截器执行链自定义一环end -->
注意地方:web项目是根据web.xml文件顺序决定拦截器执行先后顺序,纯后端可以采用@Order(1)注解方式表示过滤器先后顺序,参数越大越后
第二步:编写testAuth
public class testAuth implements Filter {
private FilterConfig config;
private static Logger log = LoggerFactory.getLogger(testAuth.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//todo 初始化参数逻辑
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//todo 过滤逻辑
}
@Override
public void destroy() {
//删除逻辑
}
}
第三步:详解第二步三种方法配置
1init方法,这里取的shiro作为其代表
使用的是代理类GenericFilterBean
继续往上找 GenericFilterBean同样实现Filter接口
GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, ServletContextAware, InitializingBean, DisposableBean
获取FilterConfig对象,将读到的参数配置信息加载到所需的代理类中
当然今天的主题不是讲shiro的配置,但可以通过已有的架构实例来指导我们,也可以通过这种方法可以添加一些自定义预配置
2 destroy()方法
顾名思义,就是销毁拦截器,只在应用退出tomcat容器才会用得到,所以一般我们只需要将拦截器配置清空就好
private FilterConfig config;
@Override
public void destroy() {
this.config = null;
}
3最重要的doFilter方法
如果你不想执行任何过滤处理,可以直接调用
chain.doFilter(request, response);
但一般我们添加过滤器其实就是对某些URL或者自定义的参数来判断是否需要过滤,举个URI过滤的例子
HttpServletRequest request1 = (HttpServletRequest) request; HttpServletResponse response1 = (HttpServletResponse) response; String requestURI = request1.getRequestURI(); if(requestURI.contains("过滤地址")){ response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); JSONObject res = new JSONObject(); res.put("code",200); res.put("message","成功"); PrintWriter writer = response.getWriter(); writer.append(res.toString()); return; }
当访问过滤地址时,执行到doFilter时直接返回json数据,不再执行下一步
然后就思考着能不能在多重过滤中手动添加一个过滤器,只要按着逻辑判断走,应该也能实现业务需求
查询FilterChain接口,发现只有一个
发现此路不通,为什么不通呢?
Filter采用的是责任链设计模式,由多个对象上下传递而组成的一条链,每个对象都可以处理请求
设计模式和初始化就限定死了不能对chain(执行链)对象进行任何的修改操作,所以从业务本身出发,不能依靠这种方法实现