来源于:http://trac.seagullproject.org/wiki/Howto/PragmaticPatterns/InterceptingFilter

Intercepting Filter((截取筛选器))

概述

Seagull使用Intercepting Filter模式,这种模式允许开发人员对每一个请求设置一个自定义的过滤链。这种过滤链允许在过滤前对数据进行预处理并在过滤后对结果进行加工处理。

当数据模型创建完毕时,在它到达它的最终目的地即我们所说的内核处理器——在大多数情况下是应用程序控制器之前,它必须经过过滤链。 意思就是说你可以过滤和转化任何被传递到你的商务处理核心的数据,并在将核心处理结果返回到客户端之前进行过滤

被传递到处理核心的典型数据是请求对象。在Seagull中也是这样,但是请求对象通过过滤链把被认为是合法的或者是已经验证的数据被映射到输入对象。当处理完毕后,处理结果又通过过滤链过滤处理并以output对象返回,最后传递到客户端。

看一个例子来帮助理解:

   $request
      $input
          //  对 $input 预处理
          SGL_Task_StripMagicQuotes()
          SGL_Task_ResolveManager()
          SGL_Task_AuthenticateRequest()
              
              // 核心处理
              $myMgr->validate()
              $myMgr->process()
              $myMgr->display()
          
          // 对 $output 进行再加工
          SGL_Task_BuildView()
          SGL_Task_BuildHeaders()
      
      $output
  echo $output->data;

更清晰的描述请看下面的UML图,请注意倒置的锥体。

http://msdn.microsoft.com/library/en-us/dnpatterns/html/Des_InterceptingFilter_Fig05.gif

自定义过滤链

不难理解开发人员可能想基于每一个请求自定义过滤链。你可能想

  • 以XML格式输出数据
  • 通过HTML到PDF的转换器来执行

Seagull默认提供了一个通用的过滤器,但是可以通过简单的配置来自定义。

this example is for building a REST server: 在模块的配置文件中,添加下面的这几行可以设置你自己的过滤链。

[RestMgr]
requiresAuth    = false
filterChain     = " SGL_Task_Init,
                    SGL_Task_ResolveManager,
                    EG_Filter_PhpToXmlSerializer,
                    EG_Filter_XmlToPhpUnserializer,
                    EG_Filter_BuildHeaders,
                    EG_CoreProcessor"

注意:最终目标,在这里是EG_CoreProcessor,必须是列表中的最后一项。

使你的过滤链可移植

按照 /branches/0.6-bugfix/lib/SGL/FrontController.php的例子创建你自己的过滤链。这里有一些使你的代码保持简洁和可重用的指南:如果你的项目使用了特殊的类库,如”My Important Client”,那么请在文件系统中创建具有自主命名空间的lib目录,如果你愿意的话也可以放在Seagull目录下,如:

seagull/lib/MIC/

并将过滤器放在显著的地方:

seagull/lib/MIC/Filters/MyFooTransform.php seagull/lib/MIC/Filters/MyBarTransform.php

将该路径添加到你的Seagull配置文件中的Configuration → General

最后修改模块的配置文件conf.ini file中的过滤器的类名和顺序:

[MyMgr]
requiresAuth    = false
filterChain     = " SGL_Task_Init,
                    SGL_Task_ResolveManager,
                    MIC_Filters_MyFooTransform,
                    MIC_Filters_MyBarTransform,
                    EG_CoreProcessor"

过滤对象承担过滤链的动态评估部分的职责。

Seagull的什么地方使用了?

目前,输出模块使用自定义的模块设置可配置的header,即text/html Content-type headers。请看模块配置文件conf.ini来看看任务是如何载入的以及任务的顺序有多重要。

别的框架如何截取Request

我了解了一下Django,它可能是目前最流行的Python的Web框架,好像他们都没听说过 intercepting filters,看他们的解决方案: http://www.djangoproject.com/documentation/middleware/

我很喜欢他们引用的过滤器,如果Seagull能引入这些过滤器那就太妙了。

更多内容请查看

 
howto/pragmaticpatterns/interceptingfilter.txt · 最后更改: 2010/05/30 00:21 (外部编辑)
 
Except where otherwise noted, content on this wiki is licensed under the following license:GNU Free Documentation License 1.2