学习Model-Glue框架的系列教程-Building your first Model-Glue Application中文理解通俗版(2)

来源:互联网 发布:网页提取软件 编辑:程序博客网 时间:2024/05/16 20:22
  1. <event-handler name="Logon">
  2. <broadcasts />
  3. <views>
  4.    <include name="body" template="dspLogon.cfm" />
  5. </views>
  6. <results />
  7. </event-handler>
      在我的上一讲里,我带领大家通看了基本的创建步骤和设计了相册应用。在这一讲里我们将开始讨论系统应用的安全性和注册模块。老实说在我创建首个Model-Glue应用时我碰到了麻烦。我不认为这是最好的答案,但我认为至今它对我一直很有用,所以我想分享他一下。
       像大多数网站,我们的应用将有注册和登陆页面。但我们怎么处理安全的问题?通常我们在Application.cfc文件里使用onRequestStart来确认一个请求是否合法,因此,举例来说,我将做如下一些事 如果一个请求来自未登陆和未注册者,我们将迫使他去那里,被废弃此次请求
        但我们在Model-Glue框架里怎么实现呢?让我们确认一些事实:Model-Glue框架定义了事件。这些事件明确定义了该Web应用能做什么。我们使用的默认的应用模板有两个事件:Home 和 Exception。当我们以非事件方式启动应用,它将使用配置文件里的默认事件。在我们这,就是Home模板。所以让我们从使Home模板安全化着手
        事件能够并且将会广播消息,当我第一次在快速手册里读到这点,并没有重视。我脑子里的看法是:有时事件需要额外的信息(比如:“我登陆了吗”),而且当事件触发时事件需要那些信息。你的事件甚至能根据结果处理。   
       那么我们怎么使用它呢?我们已经知道我们需要浏览者注册登录。所以我们可以修改Home事件来检查用户是否登录。如果他们没有,我们可以迫使他们跳到登陆界面。以下是修改好的版本
  1. <event-handler name="Home">
  2. <broadcasts>
  3.    <message name="getAuthenticated" />
  4. </broadcasts>
  5. <views>
  6.    <include name="body" template="dspBody.cfm" />
  7.    <include name="main" template="dspTemplate.cfm" />
  8. </views>
  9. <results>
  10.    <result name="notAuthenticated" do="Logon" />
  11. </results>
  12. </event-handler>
    代码里我们改变了什么?我增添了一条新的Message:getAuthenticated。我还增添了一个新的结果。结果的名字:notAuthenticated意味着只有当控制器返回的结果是notAuthenticated时才会执行。你也许猜到了,我的控制器返回的值不是authenticated就是notAuthenticated。在这里我只关心用户是否已验证。
      现在我们需要控制器来监听这事件。你也许会问-我为什么必须这样做?其他什么的不能监听事件吗。Model-Glue的例子应用只有一个控制器,但是真正商业应用也许会有许多个。你将发现我们能告知控制器去监听“Foo”事件但调用的是“goo”方法。这在你的控制器改变时尤为有用,因为它可以让我们保持事件使用原有的名字。所以请你找到你的控制器模块,找到myController,在onRequestEnd后添加一个新的消息监听器:getAuthenticated。整个模块如同下面代码:

  1. <controllers>
  2. <controller name="myController" type="controller.Controller">
  3. <message-listener message="OnRequestStart" function="OnRequestStart" />
  4. <message-listener message="OnRequestEnd" function="OnRequestEnd" />
  5. <message-listener message="getAuthenticated" function="getAuthenticated" />
  6. <!-- Message-Listener Template
  7. <message-listener message="BroadcastMessageName" function="ControllerFunctionToFire">
  8. <argument name="AnEventArgument" value="aValue" />
  9. </message-listener>
  10. -->
  11. </controller>
  12. </controllers>
  1. 如果你需要,你可以去掉注释,这里只是让你学习注释格式,正如你所看到的,我们添加了getAuthenticated监听器,它负责调用控制器里的同名方法。现在让我们添加方法到我们的控制器。打开controller/Controller.cfc文件,在OnRequestStart之前加入以下代码:
  2. <cffunction name="getAuthenticated" access="public" returntype="void" output="false" hint="I return if the user is authenticated.">
  3.     <cfargument name="event" type="ModelGlue.Core.Event" required="true">
  4.     <cfset arguments.event.addResult("notAuthenticated") />
  5. </cffunction>

            让我们一行一行来看:所有监听事件的控制器的方法都被传到一个Model-Glue事件里。这就是你所反复修改的地方。开始可能有些生涩,但你可以想象事件对象成在你的请求过程里站站停的公交车(这里的站指事件),在每个车站,一个新的值可能竟来,或出去,或者司机可能有新的指令。我可能直接添加一个事件的结果。在这里你可能发现代码永远返回未验证,因为我们未加入真正的验证逻辑    
          还好你还跟得上俺-_-#既然我们一直返回未验证,那么Home Event将会触发登录事件,我们需要增加代码:
  1. <event-handler name="Logon">
  2. <broadcasts />
  3. <views>
  4.    <include name="body" template="dspLogon.cfm" />
  5. </views>
  6. <results />
  7. </event-handler>

这段代码与前面的Home事件相当相似,我不打算广播任何事件:我只是单单包进来一个登录模板,注意到 Home事件使用了两个视图。一个称为内容模板,一个称为显示模板,通常登陆页面与其他页面显示不太一样,虽然至今我们的登陆页面dspLogon.cfm还很难看,但有行代码值得注意:
  1. <form action="#viewstate.getValue("myself")#logonattempt" method="post">
视图状态,正如帮助手册里讲到的,它是传递给视图的一系列数据,控制器能通知模型层取出数据,然后将数据放到视图状态里,这样你的视图文件便可以去用这些数据。这点我后面讲,老实说,这在当初很困老我,但现在你只需要知道Myself所对应的值是指向你的应用根路径,再加上logonattempt提交。
    今天讲了很多,总结一下(o(∩_∩)o...这段不译了,哪位路过的Helpe一下...):
The first thing I did was add a new setting, DSN, to my ModelGlue.xml file. This setting will be available to my code. You can think of it like Application variables.
    * I modified the Home event to broadcast an event. This event checks to see if we are logged in.
    * I modified the controller to check and see if the user is logged on. For this release, I simply made it return false. I did this by adding a result to my event that the Home event will notice.
    * I added the Logon event to handle displaying the logon form. Any request for the site's Home event will now force you to logon if you haven't done so.
 
 
     
原创粉丝点击