Getting Perl and Flex talking via XML

Post to Twitter

Flex and Flash are very capable tools and its often very trivial to get them talking to all different kinds of back ends. Today we will get Perl talking to Flex via XML and its easier than you might think.

To work through this you will need the following:
1. Flex Builder 3 – a free trial is available
2. Access to a web host that runs Perl, or a Perl distribution hooked to a web server of some sort.

The first thing we’ll do is create a very simple Perl script that will render out some XML:

#!/usr/bin/perl

use strict;
use XML::Writer;

print "Content-type: text/xml\n\n";

my $xml = new XML::Writer();

$xml->startTag("root");
  $xml->startTag("messages");
    $xml->dataElement(msg1=> "Hello World");
    $xml->dataElement(msg2=> "Goodbye World");
    $xml->endTag();
    $xml->endTag();
  $xml->endTag();
$xml->end();

You can hit that page with your browser and hopefully see a result like this:

<root>
	<messages>
		<msg1>Hello World</msg1>
		<msg2>Goodbye World</msg2>
	</messages>
</root>

Lets create a simple Flex application to test this out. Fire up Flex Builder 3 and call the new project “TalkToPerl”.

Creating the project

I modified my MXML page to look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[

            private function onResult():void
            {
                txt.htmlText = txt.htmlText + "<br/>Msg1: " + xmlService.lastResult.messages["msg1"];
                txt.htmlText = txt.htmlText + "<br/>Msg2: " + xmlService.lastResult.messages["msg2"];
            }
		]]>
	</mx:Script>

	<mx:HTTPService id="xmlService" result="onResult();" resultFormat="e4x" url="http://YOUR_WEB_HOST_ADDRESS/cgi-bin/perltest.cgi" />

	<mx:Panel width="350" height="280" layout="absolute" horizontalCenter="0" verticalCenter="0" color="#000000" fontSize="12" fontFamily="Verdana">
		<mx:Button x="126.5" y="10" label="Test Me" click="xmlService.send();"/>
		<mx:TextArea x="10" y="42" width="310" height="188" id="txt" verticalScrollPolicy="on"/>
	</mx:Panel>
</mx:Application>

The real trick here is that in the MX:HTTPService tag we added this attribute: resultFormat=”e4x”. E4X is EcmaScript 4 XML. This allows Flex to interpret and parse the data as XML thus making this statement make sense to retrieve the data:

[as]
xmlService.lastResult.messages["msg1"]
[/as]

Run the project and you should hopefully see something like this:

First results

Pretty easy huh? Ok, now lets pass in some parameters to the Perl script from Flex and have Perl send back something based on those parameters. We can do this by adding this code:

	<mx:HTTPService id="xmlService" result="onResult();" method="POST" resultFormat="e4x" url="http://YOUR_WEB_HOST_ADDRESS.com/cgi-bin/perltest.cgi">
		<mx:fault>Alert.show(event.toString(), event.type);</mx:fault>
        <mx:request xmlns="">
            <message>My new message</message>
        </mx:request>
	</mx:HTTPService>

We display an alert if we encounter an error, but otherwise we pass in “message” with the value “My new message” via a POST. We now need to modify the Perl script to have the ability to extract the POST variable(s) and do something with it. In this case I’ll simply place that value into the msg1 section of the XML.

#!/usr/bin/perl

use strict;
use XML::Writer;
use CGI qw(:standard);

print "Content-type: text/xml\n\n";

my $xml = new XML::Writer();

$xml->startTag("root");
  $xml->startTag("messages");
    $xml->dataElement(msg1=> param("message"));
    $xml->dataElement(msg2=> "Goodbye!");
	$xml->endTag();
$xml->endTag();
  $xml->endTag();
$xml->end();

So the final MXML is going to look like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;

            private function onResult():void
            {
                txt.htmlText = txt.htmlText + "<br/>Msg1: " + xmlService.lastResult.messages["msg1"];
                txt.htmlText = txt.htmlText + "<br/>Msg2: " + xmlService.lastResult.messages["msg2"];
            }
		]]>
	</mx:Script>


	<mx:HTTPService id="xmlService" result="onResult();" method="POST" resultFormat="e4x" url="http://YOUR_WEB_HOST_ADDRESS.com/cgi-bin/perltest.cgi">
		<mx:fault>Alert.show(event.toString(), event.type);</mx:fault>
        <mx:request xmlns="">
            <message>My new message</message>
        </mx:request>
	</mx:HTTPService>

	<mx:Panel width="350" height="280" layout="absolute" horizontalCenter="0" verticalCenter="0" color="#000000" fontSize="12" fontFamily="Verdana">
		<mx:Button x="126.5" y="10" label="Test Me" click="xmlService.send();"/>
		<mx:TextArea x="10" y="42" width="310" height="188" id="txt" verticalScrollPolicy="on"/>
	</mx:Panel>
</mx:Application>

Run the application and you should see this:

The final result

As you can see passing data to and from Flex to Perl via XML is very easy to do.

Post to Twitter

This entry was posted in ActionScript, Flex, Perl. Bookmark the permalink.

16 Responses to Getting Perl and Flex talking via XML

  1. Pingback: Getting Java and Flex talking via XML « Giant Flying Saucer

  2. Mobius says:

    Line 16 in your PERL file is unnecessary. It throws an error. $xml->end(); is sufficient.

    Also, I’ve been trying to get this to work and haven’t had any luck. I’m testing locally. I don’t think it should make a difference since I can run perl scripts locally and I can run flex apps locally. Am I wrong here?

  3. Pingback: Getting Java and Flex talking via XML | Giant Flying Saucer

  4. Mac says:

    How can i call a local Perl code inside a mxml(or actionscript) script when a button is cliked?

  5. Chad Lung says:

    @Mac,

    Use the URLLoader. If you search my blog you’ll see a lot of examples where I use URLLoader.

    Chad

  6. mac says:

    Can you give me the exact syntax..
    I tried and it did not work. I did not get any errors. But it just did not work

  7. Chad Lung says:

    @mac,

    The exact syntax is in the article. Without errors there is not much to go on. Have you tried the Flex debugger and setting some breakpoints to see if anything unusual shows up?

    Chad

  8. mac says:

    sorry for not mentioning that before. I use Linux with flex SDK.
    SO I have to write mxml in vi editor and compile it using “mlmlc code.mxml” which will generate a swf file and then run it using “firefox code.swf”

    Here is the code what I used to call perl script. My perl script and the code.mxml file are in same directory.

    var myTextLoader:URLLoader = new URLLoader();

    myTextLoader.addEventListener(Event.COMPLETE, onLoaded);

    function onLoaded(e:Event):void {
    trace(e.target.data);
    }

    myTextLoader.load(new URLRequest(“perlcode.pl”));

    I got this snippet from web and I just copied and pasted which executes when a button is clicked. The only change I made to this snippet is changed the calling script name in the last line ie. perlcode.pl

  9. Chad Lung says:

    @mac,

    My first guess is your running into a security issue on how your going about running this (loading/calling data from a server outside the security sandbox).

    Turn on the logging for the Flash Debugger Player and see what error is being logged:
    http://livedocs.adobe.com/flex/3/html/help.html?content=logging_04.html

    Chad

  10. mac says:

    Hi
    I finally installed debug version of flex and you are rite!!
    I am getting following error

    An ActionScript error has occurred:
    SecurityError: Error #2148: SWF file file:///home/mac/flexworks/flex/actionscript/src/com/example/quickstart/hw.swf cannot access local resource file:///home/mac/flexworks/flex/actionscript/src/com/example/quickstart/vlcplyr.pl. Only local-with-filesystem and trusted local SWF files may access local resources.
    at flash.net::URLStream/load()
    at flash.net::URLLoader/load()
    at com.example.quickstart::hw/alertListener()
    at com.example.quickstart::hw/__fname_click()

    Do you have any solution for this ?

  11. mac says:

    Also this is the content of the log file (log file name is “1″) that is located at /home/mac/.macromedia/Flashplayer/Logs/1

    Warning: Ignoring ‘secure’ attribute in policy file from http://fpdownload.adobe.com/pub/swz/crossdomain.xml. The ‘secure’ attribute is only permitted in HTTPS and socket policy files. See http://www.adobe.com/go/strict_policy_files for details.
    * Security Sandbox Violation ***
    Warning: Reached warning limit of 1
    SecurityError: Error #2148: SWF file file:///home/mac/flexworks/flex/actionscript/src/com/example/quickstart/hw.swf cannot access local resource file:///home/mac/flexworks/flex/actionscript/src/com/example/quickstart/vlcplyr.pl. Only local-with-filesystem and trusted local SWF files may access local resources.
    at flash.net::URLStream/load()
    at flash.net::URLLoader/load()
    at com.example.quickstart::hw/alertListener()
    at com.example.quickstart::hw/__fname_click()

  12. Chad Lung says:

    @mac,

    It sounds like you need a cross domain policy file.

    Chad

  13. mac says:

    ok.. This is new.
    However I configured crossdomain.xml iin my system(ubuntu) and I was not sure where to place it. I know I have to place it in my root directory.
    So I placed it in following directories / , /home , /home/username/ , /root

    here is the content of the crossdomain file

    I am not sure about the content of the file.

    Also I added two lines to my mxml code
    import mx.events.FlexEvent;
    protected function applicationCompleteHandler(event:FlexEvent):void
    {
    Security.loadPolicyFile(“file:///crossdomain.xml”);
    }
    my perl code and mxml are both located at
    /home/mac/flexworks/flex/actionscript/src/com/example/quickstart

    I still get same security error.

    Please help me in fixing this. This task is already due.:(

  14. mac says:

    I also changed use-network = false in flex-config.xml

    but I get a different error bcoz i have added

    xmlns:mx=”http://www.adobe.com/2006/mxml”

    in my mxml

  15. Chad Lung says:

    @mac,

    You probably want to try the Flex/Flash forums at Adobe.

    Chad

  16. mac says:

    Hi.. I some how solved that problem.

    I just want to ask you, Is it possible to send data to perl ?
    I mean in the above example, your only sending some text to flex from perl.

    But I need like sending from flex to perl

    For example consider a perl script that generate random number of names ( say ERgeknf, lfjnef, wlfkenr,) . here in flex code we have to give two datas.

    –> no:of random names to be generated
    –>no: of characters in each name

    And then we pass both these data to perl and perl in-turn generates these random numbers and inserts these datas into a SQL database table.

Comments are closed.