当前位置: 首页 > news >正文

江苏优化网站关键词建筑公司取名

江苏优化网站关键词,建筑公司取名,wordpress微信机器人高级版,龙岗网站建设联系电话今天#xff0c;我们主要讲解职责链模式的原理和实现。除此之外#xff0c;我还会利用职责链模式#xff0c;带你实现一个可以灵活扩展算法的敏感词过滤框架。下一节课#xff0c;我们会更加贴近实战#xff0c;通过剖析Servlet Filter、Spring Interceptor来看#xff0…        今天我们主要讲解职责链模式的原理和实现。除此之外我还会利用职责链模式带你实现一个可以灵活扩展算法的敏感词过滤框架。下一节课我们会更加贴近实战通过剖析Servlet Filter、Spring Interceptor来看如何利用职责链模式实现框架中常用的过滤器、拦截器。 职责链模式的原理和实现 将请求的发送和接收解耦让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链并沿着这条链传递这个请求直到链上的某个接收对象能够处理它为止。 在职责链模式中多个处理器也就是刚刚定义中说的“接收对象”依次处理同一个请求。一个请求先经过A处理器处理然后再把请求传递给B处理器B处理器处理完后再传递给C处理器以此类推形成一个链条。链条上的每个处理器各自承担各自的处理职责所以叫作职责链模式。 第一种实现如下Handler 是所有处理器类的抽象父类handle()是抽象方法每个具体的处理器类HandlerA 和HadnlerB的handle() 函数的代码结构类似如果它能处理该请求就不继续往下传递如果不能处理就需要往下传递了。 public abstract class Handler {protected Handler successor null;public void setSuccessor(Handler successor) {this.successor successor;}public abstract void handle(); }public class HandlerA extends Handler {Overridepublic void handle() {boolean handled false;//...if (!handled successor ! null) {successor.handle();}} }public class HandlerB extends Handler {Overridepublic void handle() {boolean handled false;//...if (!handled successor ! null) {successor.handle();} } }public class HandlerChain {private Handler head null;private Handler tail null;public void addHandler(Handler handler) {handler.setSuccessor(null);if (head null) {head handler;tail handler;return;}tail.setSuccessor(handler);tail handler;}public void handle() {if (head ! null) {head.handle();}} }// 使用举例 public class Application {public static void main(String[] args) {HandlerChain chain new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();} } 实际上上面的代码实现不够优雅。处理器类的handle()函数不仅包含自己的业务逻辑还包含对下一个处理器的调用也就是代码中的successor.handle()。一个不熟悉这种代码结构的程序员在添加新的处理器类的时候很有可能忘记在handle()函数中调用successor.handle()这就会导致代码出现bug。 针对这个问题我们对代码进行重构利用模板模式或者接口将调用successor.handle()的逻辑从具体的处理器类中剥离出来放到抽象父类中。这样具体的处理器类只需要实现自己的业务逻辑就可以了。重构之后的代码如下所示 public interface IHandler {boolean handle(); }public class HandlerA implements IHandler {Overridepublic boolean handle() {boolean handled false;//...return handled;} }public class HandlerB implements IHandler {Overridepublic boolean handle() {boolean handled false;//...return handled;} }public class HandlerChain {private ListIHandler handlers new ArrayList();public void addHandler(IHandler handler) {this.handlers.add(handler);}public void handle() {for (IHandler handler : handlers) {boolean handled handler.handle();if (handled) {break;}}} }// 使用举例 public class Application {public static void main(String[] args) {HandlerChain chain new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();} } 实际上职责链模式还有一种变体那就是请求会被所有的处理器都处理一遍不存在中途终止的情况。这种变体也有两种实现方式用链表存储处理器和用数组存储处理器跟上面的两种实现方式类似只需要稍微修改即可。 仅仅将handle代码的if判断去掉即可 public void handle() {for (IHandler handler : handlers) {boolean handled handler.handle();}} 职责链模式的应用场景举例 对于支持UGCUser Generated Content用户生成内容的应用比如论坛来说用户生成的内容比如在论坛中发表的帖子可能会包含一些敏感词比如涉黄、广告、反动等词汇。针对这个应用场景我们就可以利用职责链模式来过滤这些敏感词。 public interface SensitiveWordFilter {boolean doFilter(Content content); }public class SexyWordFilter implements SensitiveWordFilter {Overridepublic boolean doFilter(Content content) {boolean legal true;//...return legal;} }// PoliticalWordFilter、AdsWordFilter类代码结构与SexyWordFilter类似public class SensitiveWordFilterChain {private ListSensitiveWordFilter filters new ArrayList();public void addFilter(SensitiveWordFilter filter) {this.filters.add(filter);}// return true if content doesnt contain sensitive words.public boolean filter(Content content) {for (SensitiveWordFilter filter : filters) {if (!filter.doFilter(content)) {return false;}}return true;} }public class ApplicationDemo {public static void main(String[] args) {SensitiveWordFilterChain filterChain new SensitiveWordFilterChain();filterChain.addFilter(new AdsWordFilter());filterChain.addFilter(new SexyWordFilter());filterChain.addFilter(new PoliticalWordFilter());boolean legal filterChain.filter(new Content());if (!legal) {// 不发表} else {// 发表}} } 首先我们来看职责链模式如何应对代码的复杂性。 将大块代码逻辑拆分成函数将大类拆分成小类是应对代码复杂性的常用方法。应用职责链模式我们把各个敏感词过滤函数继续拆分出来设计成独立的类进一步简化了SensitiveWordFilter类让SensitiveWordFilter类的代码不会过多过复杂。 其次我们再来看职责链模式如何让代码满足开闭原则提高代码的扩展性。 当我们要扩展新的过滤算法的时候比如我们还需要过滤特殊符号按照非职责链模式的代码实现方式我们需要修改SensitiveWordFilter的代码违反开闭原则。不过这样的修改还算比较集中也是可以接受的。而职责链模式的实现方式更加优雅只需要新添加一个Filter类并且通过addFilter()函数将它添加到FilterChain中即可其他代码完全不需要修改。 上面介绍了如何责任链模式的原理和应用场景那么接下来我们看一下责任链模式在框架中的应用为框架提供可靠的扩展点。 Servlet Filter Servlet Filter是Java Servlet规范中定义的组件翻译成中文就是过滤器它可以实现对HTTP请求的过滤功能比如鉴权、限流、记录日志、验证参数等等。因为它是Servlet规范的一部分所以只要是支持Servlet的Web容器比如Tomcat、Jetty等都支持过滤器功能。为了帮助你理解我画了一张示意图阐述它的工作原理如下所示。 在实际项目中我们该如何使用Servlet Filter呢我写了一个简单的示例代码如下所示。添加一个过滤器我们只需要定义一个实现javax.servlet.Filter接口的过滤器类并且将它配置在web.xml配置文件中。Web容器启动的时候会读取web.xml中的配置创建过滤器对象。当有请求到来的时候会先经过过滤器然后才由Servlet来处理。主要是涉及到过滤器的处理范围。 public class LogFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 在创建Filter时自动调用// 其中filterConfig包含这个Filter的配置参数比如name之类的从配置文件中读取的}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println(拦截客户端发送来的请求.);chain.doFilter(request, response);System.out.println(拦截发送给客户端的响应.);}Overridepublic void destroy() {// 在销毁Filter时自动调用} }// 在web.xml配置文件中如下配置 filterfilter-namelogFilter/filter-namefilter-classcom.xzg.cd.LogFilter/filter-class /filter filter-mappingfilter-namelogFilter/filter-nameurl-pattern/*/url-pattern /filter-mapping 职责链模式的实现包含处理器接口IHandler或抽象类Handler以及处理器链HandlerChain。对应到Servlet Filterjavax.servlet.Filter就是处理器接口FilterChain就是处理器链。接下来我们重点来看FilterChain是如何实现的。 public final class ApplicationFilterChain implements FilterChain {private int pos 0; //当前执行到了哪个filterprivate int n; //filter的个数private ApplicationFilterConfig[] filters;private Servlet servlet;Overridepublic void doFilter(ServletRequest request, ServletResponse response) {if (pos n) {ApplicationFilterConfig filterConfig filters[pos];Filter filter filterConfig.getFilter();filter.doFilter(request, response, this);} else {// filter都处理完毕后执行servletservlet.service(request, response);}}public void addFilter(ApplicationFilterConfig filterConfig) {for (ApplicationFilterConfig filter:filters)if (filterfilterConfig)return;if (n filters.length) {//扩容ApplicationFilterConfig[] newFilters new ApplicationFilterConfig[n INCREMENT];System.arraycopy(filters, 0, newFilters, 0, n);filters newFilters;}filters[n] filterConfig;} } Spring Interceptor 刚刚讲了Servlet Filter现在我们来讲一个功能上跟它非常类似的东西Spring Interceptor翻译成中文就是拦截器。尽管英文单词和中文翻译都不同但这两者基本上可以看作一个概念都用来实现对HTTP请求进行拦截处理。 它们不同之处在于Servlet Filter是Servlet规范的一部分实现依赖于Web容器。Spring Interceptor是Spring MVC框架的一部分由Spring MVC框架来提供实现。客户端发送的请求会先经过Servlet Filter然后再经过Spring Interceptor最后到达具体的业务代码中。我画了一张图来阐述一个请求的处理流程具体如下所示。 · public class LogInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(拦截客户端发送来的请求.);return true; // 继续后续的处理}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(拦截发送给客户端的响应.);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(这里总是被执行.);} }//在Spring MVC配置文件中配置interceptors mvc:interceptorsmvc:interceptormvc:mapping path/*/bean classcom.xzg.cd.LogInterceptor //mvc:interceptor /mvc:interceptors 同样我们还是来剖析一下Spring Interceptor底层是如何实现的。 当然它也是基于职责链模式实现的。其中HandlerExecutionChain类是职责链模式中的处理器链。它的实现相较于Tomcat中的ApplicationFilterChain来说逻辑更加清晰不需要使用递归来实现主要是因为它将请求和响应的拦截工作拆分到了两个函数中实现。HandlerExecutionChain的源码如下所示同样我对代码也进行了一些简化只保留了关键代码。 public class HandlerExecutionChain {private final Object handler;private HandlerInterceptor[] interceptors;public void addInterceptor(HandlerInterceptor interceptor) {initInterceptorList().add(interceptor);}boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {HandlerInterceptor[] interceptors getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i 0; i interceptors.length; i) {HandlerInterceptor interceptor interceptors[i];if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}}}return true;}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {HandlerInterceptor[] interceptors getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i interceptors.length - 1; i 0; i--) {HandlerInterceptor interceptor interceptors[i];interceptor.postHandle(request, response, this.handler, mv);}}}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)throws Exception {HandlerInterceptor[] interceptors getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i this.interceptorIndex; i 0; i--) {HandlerInterceptor interceptor interceptors[i];try {interceptor.afterCompletion(request, response, this.handler, ex);} catch (Throwable ex2) {logger.error(HandlerInterceptor.afterCompletion threw exception, ex2);}}}} } 注意看代码里面的 applyPreHandle 和 applyPostHandle 的循环方式一个是前项循环一个是后项循环而且在applyPreHandle执行为false时 triggerAfterCompletion 也是要执行的。
http://www.zqtcl.cn/news/83863/

相关文章:

  • 优化网站平台网站建设布局
  • 网站代理在线扬州市市政建设处网站
  • 陕西 建设工程有限公司网站wordpress 评论换行
  • 个人网站能否备案开发新闻类网站
  • 购物网站支付页面制作云南网站制作一条龙全包
  • 网站空间与域名的关系免费网站建设免代码
  • 长沙网站排名优化wordpress在线代码编辑器
  • 长宁苏州网站建设公司深圳那家做网站好
  • 郑州网站推广价如何做垂直网站
  • app下载汅api免费下载大全视频扬中企业网站优化哪家好
  • 最大的网站建个普通网站
  • dede网站如何换logo免费拓客100个方法
  • 专门做效果图的网站wordpress 主题缩略图
  • 重庆公司有哪些林云seo博客
  • 西安网站建设和推广专业网站建设办公
  • 做网站主机要求用手机可以做网站吗
  • 杭州网站建设过程wordpress contact
  • 定制型网站建设合同范本东营远见网站建设公司
  • 电子商务网站建设题金华英文网站建设
  • 网站开发招聘 领英小区住宅可以注册公司吗
  • 郑州网站维护wordpress自定义按钮
  • 管理类手机网站江门网站设计制作
  • 罗马尼亚网站后缀电子商务网站建设与维护 答案
  • 类似快手网站开发淘宝返利网站怎么做
  • 淘宝客网站做好了该怎么做北京兼职做网站推广
  • 网站维护和推广网站维护推广的方案
  • 智慧团建入口登录网站用html5做的静态网站
  • 迎中国建设银行网站重庆快速排名
  • html网页模板素材下载黄冈网站建设优化排名
  • 深圳 旅游 网站建设网站根目录怎么找