说明:
- 在servlet的doDispatch方法中依次触发责任链的applyPreHandle的前置处理方法、applyPostHandle的后置处理方法 。
- 前置处理方法applyPreHandle会遍历责任链上的处理器从前往后依次处理,后置处理方法applyPostHandle会遍历责任链上的处理器从后往前依次处理 。
- 处理器的驱动由责任链对象负责依次触发,非处理器对象自驱执行 。

文章插图
- Servlet过滤器是在JAVA Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改 , 是个典型的责任链 。
- 在Servlet被调用之前检查Request对象并支持修改Request Header和Request内容 。
- 在Servlet被调用之后检查Response对象并支修改Response Header和Response内容 。
public interface Filter {public void init(FilterConfig filterConfig) throws ServletException;public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;public void destroy();}public class TimeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("time filter init");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 1、执行处理的逻辑System.out.println("time filter doFilter");// 2、执行责任链当中的下一个 Filter 对象,等价于执行 FilterChain 的internalDoFilter方法filterChain.doFilter(servletRequest, servletResponse);}}说明:- Servlet过滤器类要实现javax.servlet.Filter接口,该接口定义了通用的3个方法 。
- init方法:负责Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例过程中调用这个方法 。
- doFilter方法:当客户请求访问与过滤器关联的URL时,Servlet容器会调用该方法 。
- destroy方法:Servlet容器在销毁过滤器实例前调用该方法,可以释放过滤器占用的资源 。
public final class ApplicationFilterChain implements FilterChain {// 责任链上 Filter 的维护对象private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];//责任链上待执行的 Filter 对象private int pos = 0;// 责任链上拥有的 Filter 数量private int n = 0;void addFilter(ApplicationFilterConfig filterConfig) {// 避免重复添加Filterfor(ApplicationFilterConfig filter:filters)if(filter==filterConfig)return;// 按需进行扩容if (n == filters.length) {ApplicationFilterConfig[] newFilters =new ApplicationFilterConfig[n + INCREMENT];System.arraycopy(filters, 0, newFilters, 0, n);filters = newFilters;}// 保存Filter 对象filters[n++] = filterConfig;}}说明:- ApplicationFilterChain作为Filter的责任链,负责责任链的构建和执行 。
- 责任链通过ApplicationFilterConfig类型的数组对象filters保存Filter处理器 。
- 责任链上处理器的添加通过保存到数组filters来实现 。
public final class ApplicationFilterChain implements FilterChain {// 责任链上 Filter 的维护对象private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];//责任链上待执行的 Filter 对象private int pos = 0;// 责任链上拥有的 Filter 数量private int n = 0;// 责任链的执行private void internalDoFilter(ServletRequest request,ServletResponse response)throws IOException, ServletException {// 在责任链未执行完的情况下执行责任链if (pos < n) {// 获取当前待执行的 Filter , 同时递增下一次待执行责任链的下标ApplicationFilterConfig filterConfig = filters[pos++];try {Filter filter = filterConfig.getFilter();if( Globals.IS_SECURITY_ENABLED ) {// 省略相关代码} else {filter.doFilter(request, response, this);}} catch (Throwable e) {}return;}try {if ((request instanceof HttpServletRequest) &&(response instanceof HttpServletResponse) &&Globals.IS_SECURITY_ENABLED ) {// 执行正常的业务逻辑} else {servlet.service(request, response);}} catch (Throwable e) {e = ExceptionUtils.unwrapInvocationTargetException(e);throw new ServletException(sm.getString("filterChain.servlet"), e);}}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CORS 跨域资源共享在Spring Boot中的实现
- Java面试题之SpringBoot 框架
- 一文读懂Spring框架中的不同类型事件
- RouterSploit:一款功能强大的嵌入式设备渗透测试框架
- 校友眼中的李雪琴是个“怪人”,内耗严重,父母离婚是病因!
- 杨梅核能吞吗?杨梅核吞入胃中的好处
- 杭州电子厂老板,25年来待客只用“假茅台”,行家:高手中的高手
- 筱在名字中的寓意是什么
- 薛平贵中的西凉是哪里 西凉是哪里
- 祭祀之礼是指 祭祀之礼是指五礼中的
