coldfusion_利用ColdFusion功能为您的Flex应用增压

coldfusion

There are quite a few tutorials here at SitePoint that can help you grasp some of the key principles of creating Rich Internet Applications (RIAs) using Flex and AIR. You’ll find that most development undertakings in Flex will involve a back-end application to interact with the Flex client.

SitePoint上有很多教程,可以帮助您掌握使用Flex和AIR创建富Internet应用程序(RIA)的一些关键原则。 您会发现,Flex中的大多数开发工作都将涉及与Flex客户端进行交互的后端应用程序。

Let’s discuss some of the theories and principles behind what makes up a Flex application, and then put those principles into practice with a ColdFusion app. We’ll assume here that you have some experience already with ColdFusion development.

让我们讨论构成Flex应用程序背后的一些理论和原理,然后将这些原理与ColdFusion应用程序一起付诸实践。 我们在这里假设您已经具有ColdFusion开发的一些经验。

Pay attention, because there’s a quiz at the end. The first 100 people to complete the quiz will win themselves a copy of Getting Started With Flex 3, thanks to our sponsor, Adobe. Take the quiz!

请注意,因为最后有一个测验。 多亏了我们的赞助商Adobe,前100位完成测验的人将赢得一份《 Flex 3入门》的副本。 参加测验!

了解富互联网应用程序的体系结构 (Understanding a Rich Internet Application’s Architecture)

From a high level point of view, the common systems architecture of a web application usually comprises three layers.

从高级的角度来看,Web应用程序的通用系统体系结构通常包括三层。

The bottom tier consists of a data storage layer, usually a relational database system such as Microsoft’s SQL Server, Oracle, or MySQL. Such a layer provides a relational table model that can be used to store and retrieve application data.

底层由数据存储层组成,通常是关系数据库系统,例如MicrosoftSQL Server,Oracle或MySQL。 这样的层提供了可用于存储和检索应用程序数据的关系表模型。

The layer above the data storage layer is known as the application server, or middleware. Commonly used technologies in this playground are Adobe’s ColdFusion, Java, PHP, Ruby on Rails, or .NET. Those platforms are used to develop business and data access logic.

数据存储层上方的层称为应用程序服务器或中间件。 该游乐场中常用的技术是Adobe的ColdFusion,Java,PHP,Ruby on Rails或.NET。 这些平台用于开发业务和数据访问逻辑。

On top of that, or perhaps even embedded in the middleware, we’ll find a layer responsible for HTTP delivery – that is, web servers like IIS or Apache. In Rich Internet Applications, architects sometimes have to deal with other protocols besides HTTP: technologies such as Flash Media Server, for example, support the real-time streaming protocol RTMP.

最重要的是,甚至可能嵌入在中间件中,我们将找到一个负责HTTP传递的层-即IIS或Apache之类的Web服务器。 在Rich Internet Applications中,架构师有时还必须处理HTTP以外的其他协议:例如Flash Media Server等技术支持实时流协议RTMP。

In my earlier tutorial, I showed how a Flex application could communicate with other applications and data on the client side. This time, we’ll now communicate with our business and data layers on the server side.

在我以前的教程中 ,我展示了Flex应用程序如何与客户端上的其他应用程序和数据进行通信。 这次,我们现在将与服务器端的业务和数据层进行通信。

Flex如何沟通 (How Flex Communicates)

Flex can access remote data mainly by three different approaches:

Flex可以主要通过三种不同的方法来访问远程数据:

  • HTTP calls to flat files, XML files or dynamic URLs that deliver data Flex can work with

    HTTP调用可提供Flex数据的平面文件,XML文件或动态URL
  • SOAP-based web service calls

    基于SOAP的Web服务调用
  • Action Message Format (AMF) remote object calls.

    操作消息格式(AMF)远程对象调用。

Each of these methods is represented by different ActionScript classes and MXML tags. It’s fair to say that the MXML tag syntax is probably easier to use when coming from a ColdFusion background, because you’re comfortable being able to use a similar syntax to ColdFusion’s CFML syntax.

这些方法中的每一个都由不同的ActionScript类和MXML标签表示。 可以说,来自ColdFusion背景的MXML标记语法可能更易于使用,因为您可以使用与ColdFusion的CFML语法类似的语法。

HTTPService:通过HTTP检索数据 (HTTPService: Retrieving Data Over HTTP)

Let’s think about the tag mx:HTTPService. Unsurprisingly, this is an HTTP-based service, which we can use to grab some data from elsewhere at runtime. In MXML, such a service would be declared as below:

让我们考虑一下标签mx:HTTPService 。 毫不奇怪,这是一个基于HTTP的服务,我们可以使用它在运行时从其他地方获取一些数据。 在MXML中,这样的服务将声明如下:

<mx:HTTPService id="dataService"
url="http://www.example.com/xmlfile.xml" />

The id attribute provides a reference to the service object. The url attribute points to a static XML file that’s accessible via HTTP, but could also point to a local file, like so:

id属性提供对服务对象的引用。 url属性指向可通过HTTP访问的静态XML文件,但也可以指向本地文件,如下所示:

<mx:HTTPService id="dataService" url="xmlfile.xml" />

In this case the Flex application would expect to find the xml file in the same path as itself.

在这种情况下,Flex应用程序将期望在与自身相同的路径中找到xml文件。

Naturally, it’s possible to have ColdFusion generate some XML for us. Here’s a very simple way of doing this:

自然,可以让ColdFusion为我们生成一些XML。 这是一种非常简单的方法:

<cfsavecontent variable="xmlContent"><data>
   <result>            
       <item>Taxes</item>
       <amount>2000</amount>
   </result>
   ...
</data></cfsavecontent>
<cfcontent reset="true" type="text/xml"><cfoutput>#xmlContent#</cfoutput>

The tag stores created static or dynamic content in a variable, xmlContent. We then use a cfcontent tag to reset any output we may have created earlier and specify a text/xml content-type. We then deliver the content of the variable xmlContent using a simple cfoutput tag. Voilà, out comes some XML.

标签将创建的静态或动态内容存储在变量xmlContent 。 然后,我们使用cfcontent标记重置我们之前创建的所有输出,并指定text/xml内容类型。 然后,我们使用简单的cfoutput标记传递变量xmlContent的内容。 VoilÃ出来了一些XML。

On the next page, we’ll look at a Flex application that would consume that XML.

在下一页上,我们将看一个使用XML的Flex应用程序。

A Flex application to cater for such a service call would look like:

满足此类服务调用的Flex应用程序如下所示:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application  
 xmlns:mx="http://www.adobe.com/2006/mxml"  
 layout="horizontal"  
 creationComplete="cfmFile.send()">  
   <mx:Script>  
       <![CDATA[  
           import mx.controls.Alert;  
           import mx.rpc.events.ResultEvent;  
           import mx.rpc.events.FaultEvent;  
           import mx.collections.ArrayCollection;  
           [Bindable]  
           private var budgetData:ArrayCollection = new ArrayCollection();  
           private function cfmFileRH(e:ResultEvent):void  
           {  
               budgetData = e.result.data.result as ArrayCollection;  
           }  
           private function cfmFileFH(e:FaultEvent):void  
           {  
               mx.controls.Alert.show(e.fault.faultString,"Error when loading XML");  
           }  
       ]]>  
   </mx:Script>  
   <mx:HTTPService  
   id="cfmFile"  
   url="http://example.com/budgetXML.cfm"  
   result="cfmFileRH(event)"  
   fault="cfmFileFH(event)"  
   />  
   <mx:DataGrid dataProvider="{budgetData}" >  
   </mx:DataGrid>  
</mx:Application>

Here’s what’s happening: we’re using an mx:HTTPService to grab some data, and storing the result from the service in a variable named budgetData. The creationComplete event handler on the tag sends the HTTPService request when the application is created. Finally, a mx:DataGrid object displays the data as a table.

这是发生的事情:我们正在使用mx:HTTPService来获取一些数据,并将服务的结果存储在名为budgetData的变量中。 creationComplete程序时,标记上的creationComplete事件处理程序将发送HTTPService请求。 最后,一个mx:DataGrid对象将数据显示为表格。

Looking closely at the mx:HTTPService we can see that it includes two attributes: result and fault. In Flex, any data service request is dealt with asynchronously, meaning that the Flex application will immediately broadcast a result event instead of waiting for a response. All service tags offer the attributes result and fault to deal with either of these outcomes. In those attributes you’d just specify the name of the method you’d like to be called whenever a result (or a fault) comes back from the service call.

仔细查看mx:HTTPService我们可以看到它包含两个属性: resultfault 。 在Flex中,任何数据服务请求都是异步处理的,这意味着Flex应用程序将立即广播结果事件,而不是等待响应。 所有服务标签都提供属性resultfault来处理这些结果中的任何一个。 在这些属性中,您只需指定您希望在服务调用返回结果(或错误)时调用的方法的名称。

Practically speaking, an instance of mx:HTTPService is limited to GET and POST requests, although in principle other requests can be issued – but these are unavailable unless the HTTP requests are being routed via a proxy server, such as Adobe’s BlazeDS or LiveCycle Data Services. The reason for that limitation is the security model of the Flash Player, which only supports direct GET or POST calls via HTTP. That’s where another concept enters the game: a cross-domain policy file.

实际上, mx:HTTPService的实例仅限于GETPOST请求,尽管原则上可以发出其他请求-除非HTTP请求通过代理服务器(如Adobe的BlazeDSLiveCycle Data Services)路由,否则这些请求将不可用。 。 出现此限制的原因是Flash Player的安全模型,该模型仅支持通过HTTP直接进行GETPOST调用。 这就是另一个概念进入游戏的地方:跨域策略文件。

Normally, a Flash-based application using an mx:HTTPService or a SOAP-based web service may only retrieve data from a service or file stored on the same server as the .swf file. To determine whether the data is being pulled from the same domain, Flash Player compares the domain names used for the Flash file and the remote data source. This means that an application loaded from http://localhost/test.swf is unable to access HTTP data from http://127.0.0.1/data/xmlfile.xml – even though they are the same server. One solution is to use a cross-domain policy file, named crossdomain.xml, placed in the web root of the server that’s meant to provide the data. You can learn more about how to use a cross-domain policy file in Adobe’s documentation.

通常,使用mx:HTTPService或基于SOAP的Web服务的基于Flash的应用程序只能从与.swf文件存储在同一服务器上的服务或文件中检索数据。 为了确定是否从同一域中提取数据,Flash Player会比较用于Flash文件和远程数据源的域名。 这意味着从http://localhost/test.swf加载的应用程序无法访问来自http://127.0.0.1/data/xmlfile.xml的HTTP数据-即使它们是同一服务器。 一种解决方案是使用一个名为crossdomain.xml的跨域策略文件,该文件位于旨在提供数据的服务器的Web根目录中。 您可以在Adobe文档中了解有关如何使用跨域策略文件的更多信息

Next, let’s find out about sending request parameters within Flex.

接下来,让我们了解有关在Flex中发送请求参数的信息。

发送请求参数 (Sending Request Parameters)

Perhaps you need to send parameters to your service. The easiest way to pass in parameters is by adding an mx:request tag as a nested tag of the HTTP service. Let’s imagine we need to send two parameters, dataMethod and userType, to a ColdFusion script. We’d use the mx:request element like so:

也许您需要将参数发送到您的服务。 传递参数的最简单方法是添加mx:request标记作为HTTP服务的嵌套标记。 假设我们需要将两个参数dataMethoduserType发送到ColdFusion脚本。 我们将像这样使用mx:request元素:

<mx:HTTPService id="dataService" url="http://example.com/sendDataRequest.cfm" method="POST">
  <mx:request>  
      <dataMethod>getAll</dataMethod>  
      <userType>administrator</userType>  
   </mx:request>  
</mx:HTTPService>

Since we’re using the HTTP POST method, all the request variables we’re creating here will become ColdFusion variables in ColdFusion’s FORM scope. On the ColdFusion side, we’re therefore going to end up with FORM.dataMethod as well as FORM.userType on the ColdFusion template. If you’d chosen HTTP GET (by specifying method="GET"), your request data would become URL variables: URL.userType and URL.dataMethod in this case.

由于我们使用的是HTTP POST方法,因此我们在此处创建的所有请求变量都将成为ColdFusion的FORM范围内的ColdFusion变量。 因此,在ColdFusion方面,我们将以ColdFusion模板上的FORM.dataMethodFORM.userType 。 如果选择了HTTP GET (通过指定method="GET" ),则请求数据将成为URL变量:在这种情况下为URL.userTypeURL.dataMethod

So far we’ve just looked into returning XML data via HTTP services from ColdFusion templates. Although that’s a very common way to interact with HTTP services and ColdFusion, there are some other, alternative return formats for HTTP services that in some occasions might be more appropriate to use:

到目前为止,我们只是研究了通过ColdFusion模板通过HTTP服务返回XML数据。 尽管这是与HTTP服务和ColdFusion进行交互的一种非常常见的方式,但是对于HTTP服务,还有其他一些替代的返回格式,在某些情况下可能更适合使用:

  • object: response data is XML and will be converted into a tree of ActionScript objects (ArrayCollection, ObjectProxy)

    object :响应数据为XML,并将转换为ActionScript对象树( ArrayCollectionObjectProxy )

  • xml: response data is XML and will be converted into an ActionScript object of type XMLnode – this is a legacy format which is only here for compatibility; it’s best to avoid using it.

    xml :响应数据是XML,将转换为XMLnode类型的ActionScript对象–这是一种旧格式,仅在此处用于兼容性; 最好避免使用它。

  • e4x: response data is XML and will be converted into an ActionScript XML object

    e4x :响应数据为XML,并将转换为ActionScript XML对象

  • flashvars: response data is a chain of key/value-pairs: name1=value1&'name2=value2, and so on

    flashvars :响应数据是键/值对的链: name1=value1&'name2=value2 ,依此类推

  • text: response data is text, no conversion happens.

    text :响应数据是文本,不进行任何转换。

resultFormat="object" is the default, and is quite often the right way to go. If you want to work with XML instead of ArrayCollections and ObjectProxy, e4x (ECMAScript for XML) is the preferred result format - xml makes use of a deprecated set of API classes that's part of Flex for compatibility reasons only.

Providing a Service with ColdFusion

So: we've spent a good amount of this article talking about HTTP services and the general structure of a service. Now that we understand how these work, discussing web services and remote objects becomes much easier.

Let's take the following ColdFusion component that offers one simple echo method to the outside world, and try to build a Flex client that hooks into that CFC:

ColdFusion offers two ways of exposing the functionality of that component's method to a caller: as a SOAP-based web service or as a remote object. Let's try each.

SOAP

Starting with the SOAP web service, we've made the echo method a web service method by setting the attribute access="remote" in the cffunction tag. At the same time, this setting will enable us to call the method as a remote object. We'd like to retrieve the data in the WSDL format, which can be accomplished simply by adding ?WSDL to the end of the URL.

To grab that WSDL in Flex, we start off using a mx:WebService, which is structured in much the same manner as a mx:HTTPService:

<mx:WebService
 id="dataWS"    
 wsdl="http://example.com/service.cfc?WSDL"    
 result="onDataServiceResult(event)"    
 fault="onDataServiceFault(event)"    
/>

With web services you'll quite often find that a service offers multiple methods, and that you'd prefer to specify a result or fault handler method per service. That's possible when using mx:operation:

Providing parameters to web service calls works in a similar way to providing those to HTTP service calls - via mx:request - but may also be done by using a syntax familiar to developers coming from languages like Java or C++:

dataWS.echo("Hello")
Action Message Format

Now, let's try this with the Action Message Format (AMF). AMF is a protocol that's been around for quite a while, and AMF3's specification was publicly released by Adobe in December 2007. On the server side you'd need an AMF3-enabled service - luckily, as a ColdFusion developer you're ready to provide this type of service right out of the box.

In Flex we can use the mx:RemoteObject tag to communicate with remote objects:

Comparing this code with the equivalent web service declaration in Flex, there are a few small differences: we're dealing with a destination named "ColdFusion" now, and mx:operation has changed to mx:method.

When one first sets up a Flex project for ColdFusion in Flex Builder, the setup wizard will ask a bunch of questions regarding the location of the ColdFusion server, its port, URL, and context root. That information provided will then be used at the compile time of the Flex application to provide Flex with the details of your AMF URL. This works smoothly and easily for simple data types such as strings or Booleans, or even built-in ColdFusion types such as arrays and structures.

You may even wish to deal with entire objects from your application's business domain, and transfer them back and forth. There's a design pattern called data transfer object or value object that describes such a process, and it's fairly simple to use this method with ColdFusion components. Your service configuration in Flex will mostly remain the same, but instead of sending or expecting simple types from your remote object call, it will be a domain object: an object that represents a customer, shopping cart, employee, or whatever it is you plan to deal with. To allow Flex to deal with such complex object types, ColdFusion has to know about them as well, and there would have to be an equivalent component in ColdFusion. Here's a CFC that describes a user:

<cfcomponent displayname="User" output="false">
  <cfproperty name="user_id" type="numeric" />    
  <cfproperty name="user_name" type="string" />    
  <cffunction name="init" access="public" returntype="example.User" output="false">    
     <cfargument name="user_id" type="numeric" required="false"  />    
     <cfargument name="user_name" type="string" required="false"  />    
     <cfset this['user_id'] = arguments.user_id />    
     <cfset this['user_name'] = arguments.user_name />    
     <cfreturn this />    
  </cffunction>    
</cfcomponent>    

In the following minimal ActionScript 3 class, we also describe what a User object ought to contain:

The metadata tag [Bindable] allows User to be used in Flex data bindings. [RemoteClass(alias="example.User")] maps the CFC type example.User on the server end to the User class here in ActionScript.

Now What?

Where do we go from here? If you're only using ColdFusion, my guess is that you'll find it's easier to just use RemoteObjects for these kinds of projects. If you have a mixed environment comprising multiple technologies, it might be worth looking into web services and HTTP service calls to load XML. Either way, you're now equipped to deal with either situation: time to have fun!

Think you're ready to kick butt with ColdFusion? Why not test your newfound knowledge with our quiz - just five easy questions, and all the answers were right here in this article. The first 100 people to take our quiz will win a copy of Getting Started with Flex delivered straight to your door absolutely free. Grab yours!

 resultFormat="object" is the default, and is quite often the right way to go. If you want to work with XML instead of ArrayCollections  and ObjectProxy , e4x (ECMAScript for XML) is the preferred result format - xml makes use of a deprecated set of API classes that's part of Flex for compatibility reasons only.

Providing a Service with ColdFusion

So: we've spent a good amount of this article talking about HTTP services and the general structure of a service. Now that we understand how these work, discussing web services and remote objects becomes much easier.

Let's take the following ColdFusion component that offers one simple echo method to the outside world, and try to build a Flex client that hooks into that CFC:

ColdFusion offers two ways of exposing the functionality of that component's method to a caller: as a SOAP-based web service or as a remote object. Let's try each.

SOAP

Starting with the SOAP web service, we've made the echo method a web service method by setting the attribute access="remote" in the cffunction tag. At the same time, this setting will enable us to call the method as a remote object. We'd like to retrieve the data in the WSDL format, which can be accomplished simply by adding ?WSDL to the end of the URL.

To grab that WSDL in Flex, we start off using a mx:WebService , which is structured in much the same manner as a mx:HTTPService :

<mx:WebService
 id="dataWS"    
 wsdl="http://example.com/service.cfc?WSDL"    
 result="onDataServiceResult(event)"    
 fault="onDataServiceFault(event)"    
/>

With web services you'll quite often find that a service offers multiple methods, and that you'd prefer to specify a result or fault handler method per service. That's possible when using mx:operation :

Providing parameters to web service calls works in a similar way to providing those to HTTP service calls - via mx:request - but may also be done by using a syntax familiar to developers coming from languages like Java or C++:

dataWS.echo("Hello")
Action Message Format

Now, let's try this with the Action Message Format (AMF). AMF is a protocol that's been around for quite a while, and AMF3's specification was publicly released by Adobe in December 2007. On the server side you'd need an AMF3-enabled service - luckily, as a ColdFusion developer you're ready to provide this type of service right out of the box.

In Flex we can use the mx:RemoteObject tag to communicate with remote objects:

Comparing this code with the equivalent web service declaration in Flex, there are a few small differences: we're dealing with a destination named "ColdFusion" now, and mx:operation has changed to mx:method .

When one first sets up a Flex project for ColdFusion in Flex Builder, the setup wizard will ask a bunch of questions regarding the location of the ColdFusion server, its port, URL, and context root. That information provided will then be used at the compile time of the Flex application to provide Flex with the details of your AMF URL. This works smoothly and easily for simple data types such as strings or Booleans, or even built-in ColdFusion types such as arrays and structures.

You may even wish to deal with entire objects from your application's business domain, and transfer them back and forth. There's a design pattern called data transfer object or value object that describes such a process, and it's fairly simple to use this method with ColdFusion components. Your service configuration in Flex will mostly remain the same, but instead of sending or expecting simple types from your remote object call, it will be a domain object: an object that represents a customer, shopping cart, employee, or whatever it is you plan to deal with. To allow Flex to deal with such complex object types, ColdFusion has to know about them as well, and there would have to be an equivalent component in ColdFusion. Here's a CFC that describes a user:

<cfcomponent displayname="User" output="false">
  <cfproperty name="user_id" type="numeric" />    
  <cfproperty name="user_name" type="string" />    
  <cffunction name="init" access="public" returntype="example.User" output="false">    
     <cfargument name="user_id" type="numeric" required="false"  />    
     <cfargument name="user_name" type="string" required="false"  />    
     <cfset this['user_id'] = arguments.user_id />    
     <cfset this['user_name'] = arguments.user_name />    
     <cfreturn this />    
  </cffunction>    
</cfcomponent>    

In the following minimal ActionScript 3 class, we also describe what a User object ought to contain:

The metadata tag [Bindable] allows User to be used in Flex data bindings. [RemoteClass(alias="example.User")] maps the CFC type example.User on the server end to the User class here in ActionScript.

Now What?

Where do we go from here? If you're only using ColdFusion, my guess is that you'll find it's easier to just use RemoteObjects for these kinds of projects. If you have a mixed environment comprising multiple technologies, it might be worth looking into web services and HTTP service calls to load XML. Either way, you're now equipped to deal with either situation: time to have fun!

Think you're ready to kick butt with ColdFusion? Why not test your newfound knowledge with our quiz - just five easy questions, and all the answers were right here in this article. The first 100 people to take our quiz will win a copy of Getting Started with Flex delivered straight to your door absolutely free. Grab yours!

翻译自: https://www.sitepoint.com/flex-app-coldfusion-power/

coldfusion

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值