Sunday, July 5, 2009

Adobe Flex with Struts 2 using HttpService

Using HttpService is the easiest way in which you can integrate Adobe Flex and Struts 2. As an example I will show you how you can create a registration form in Adobe Flex which calls a struts 2 action to create new users. Note that this example is very simple and for demonstration purposes. I am not adding any validation in flex and not even creating the users in a database. All I show you is how you can pass data between flex and struts.

First let me show you the steps you need to perform in Adobe Flex:

Step 1

Create the registration form in mxml:

<mx:Form label="Registration Form">
<mx:FormHeading label="Registration Form">
</mx:FormHeading>
<mx:FormItem label="First Name">
<mx:TextInput id="firstName">
</mx:TextInput>
</mx:FormItem>
<mx:FormItem label="Last Name">
<mx:TextInput id="lastName">
</mx:TextInput>
</mx:FormItem>
<mx:FormItem label="Email">
<mx:TextInput id="email">
</mx:TextInput>
</mx:FormItem>
<mx:FormItem label="Username">
<mx:TextInput id="username">
</mx:TextInput>
</mx:FormItem>
<mx:FormItem label="Password">
<mx:TextInput id="password" displayAsPassword="true">
</mx:TextInput>
</mx:FormItem>
<mx:FormItem>
<mx:Button label="Register" click="registerUser()"/>
</mx:FormItem>
</mx:Form>

Step 2

Create the HttpService object:

<mx:HTTPService id="registerService" showBusyCursor="true" useProxy="false" url="register.action" resultFormat="e4x" method="POST" result="registerConfirmation(event)" fault="registerFailed(event)"/>

  • register.action is the Struts 2 action that registers the user

  • registerConfirmation(event) is the function that is called if the http service call is successful.

  • registerFailed(event) is the function that is called if an error occurs. For example if the server is down. The event object gives you access to any xml/html that might be returned upon the call of the action.

  • resultFormat specifies in which format you want to view the results. It can be text, xml or an object. There are 5 possible values for this field:
    • object - An XML object is returned and is parsed as a tree of ActionScript objects

    • xml - Returns literal XML in an XMLNode object

    • e4x - Returns literal XML that can be accessed using ECMAScript for XML(E4X) expressions.

    • flashvars - The result is text in flashvars format, value pairs separated by ampersands. Flex returns this result in an actionscript object

    • array - The result is XML that is returned in an Array even if there is only one top level node.


Step 3

Write the actionscript call to submit the form:

public function registerUser():void {
var params:Object = { 'user.firstName': firstName.text,'user.lastName': lastName.text, 'user.email':email.text, 'user.password':password.text };
this.registerService.send(params);
}


Step 4

Create registerConfirmation(). This method checks whether the registration was successful. We can know that by inspecting the XML that is returned.

private function registerConfirmation(event:ResultEvent):void {
var xml:XML=XML(event.result);
if (xml != null && xml.item == true) {
mx.controls.Alert.show("Registration Successful!");
}
else {
mx.controls.Alert.show("The registration was not successful.");
}
}}


Step 5

If we can't call the action on the server because of some networking issue we also should give some feedback to the user.
   
/**
* Display a message to the user explaining what went wrong
*/
private function registerFailed(event:FaultEvent):void {
mx.controls.Alert.show(event.fault.message);
}


Now let's create our Struts 2 Action:

Step 1

Create RegisterAction.java

package uk.co.spltech.web.actions;

import uk.co.spltech.beans.User;

import com.opensymphony.xwork2.ActionSupport;

/**
* Creates a new user
*
* @author Armindo Cachada
*
*/
public class RegisterAction extends ActionSupport {

private User user;

private Boolean success;

public Boolean getSuccess() {
return success;
}

public void setSuccess(Boolean success) {
this.success = success;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

/**
* Registers a user
*
* @return
*/
public String register() {
System.out.println("Checking user");
if ( this.getUser()!= null) {
User u = this.getUser();
if (u.getEmail()!= null && !u.getEmail().equals("") && u.getPassword()!= null
&& !u.getPassword().equals("") ) {
System.out.println("Successfully registered user with email=" + u.getEmail());
this.success=true;
}
else {
this.success=false;
System.out.println("Error registering user");
}
}
else {
this.success=false;
System.out.println("Error registering user");
}

return SUCCESS;

}

}


Step 2

Add action name='register' to struts.xml


<package name="user" extends="struts-default">
<action name="register" method="register" class="uk.co.spltech.web.actions.RegisterAction">
<result type="xslt"> <param name="exposedValue">{success}</param></result>
</action>
</package>


Source for "Adobe Flex with Struts 2 using HttpService" Example

To compile this example you will need to copy the following libraries to the lib folder:

commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-logging.jar
freemarker-2.3.13.jar
ognl-2.6.11.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar
struts2-convention-plugin-2.1.6.jar

14 comments:

Anonymous said...

Hi, your article is very interesting but I dont understand how flex gets the data from struts (the value of 'success' in this case). Could you provide more details/explanations about this step?
More over, I have the following error when I try to run the application:
Unable to render XSLT Template, 'null'
Error transforming result

Maybe I am missing something...
Thank you!

Armindo Cachada said...

The success variable is used by Adobe Flex to determine whether the registration succeeded or not. This value is supposed to be rendered into XML. This XML is returned to XML in the http response.

Regarding your error. Can you provide more information on what circumstances it happened? Are you using Struts 2/2.1, JDK 5 or 6?

Armindo Cachada said...

This XML is returned to ~Adobe Flex" in the http response.

Anonymous said...

Im using struts 2.1 and jdk 1.6

Actually, I think I forgot the most usefull part of the error which is [unknown location]. I guess struts wants a parameter named "location" in the result node (struts.xml).

If I understand well, struts is supposed to build an xml file with the variable "success" into it, and then send back this response to Flex ?

karima said...

Hi everybody..
Thank you very much for your document, it is so useful bu i have difficulty to run your application on the server (Apache Tomcat 6.0).. please can you tell me which file i must run ?? And thnak an other time..

Armindo Cachada said...

I have tried the example in apache tomcat 6 and it works fine. The instructions on how to run it:

1. Download Tomcat 6
2. Start tomcat using startup.sh or startup.bat
3. Download example5.zip
4. Import the project into eclipse and copy the jars I mentioned in my post to example5/lib
5. Change local.properties to point to your tomcat webpapps directory.
6. Change the classpath in build.xml to point to the lib folder in tomcat
7. run ant to create the war file. The build script should take care of copying the war file directly to your webapps directory in tomcat.

Now go to your browser at http://localhost:8080/example5 and you should see a registration form in Adobe Flex.

Regarding the render XSLT template error. I suspect you might be missing some library. Can you check that you included all the jars I mentioned in my post? Are you using JBOSS/Tomcat?

Anonymous said...

I think I had all libraries but nevermind. I now use remoteObject with BlazeDS and it is really better to me.
Thank you anyway.

Anonymous said...

Hi
I have deployed this application and I get the same error. Unable to render XSLT Template, 'null'. Error Trsnsforming Result.

I'm using Tomcat 6.0.20, java version 1.6.0_13. I have copied all the eight libraries that you have mentioned.

Please advice

Thank you
Krishna

Anonymous said...

Is it possible to debug the above example5 application in eclipse? when I created a new server and tried to add a project, there are'nt any Projects under "Available Resources".

prathibha said...

hi Your post is nice but as mentioned by someone above I am also getting the following error
ERROR: 'Operation not supported.'
ERROR - XSLTResult.execute(365) | Unable to render XSLT Template, 'null'
javax.xml.transform.TransformerException: Operation not supported. - [unknown location]

Can you please help me

Anonymous said...

Hi,

Your post have really helped me a lot... But i am getting an error

ERROR: 'Operation not supported.'
ERROR - XSLTResult.execute(365) | Unable to render XSLT Template, 'null'
javax.xml.transform.TransformerException: Operation not supported. - [unknown location]

can you please help me

Anonymous said...

Hi,
I m using struts1.1. can u please help me to integrate it with flex as front end.

Beyond Birth and Death said...

Hello,

I used your example and deployed it on JBoss 5.1 GA (JDK6). It worked flawlessly. Thank you for your effort. I really appreciate it.

Cheers!!

Beyond Birth and Death said...

Hari,

I used your example and deployed it on JBoss 5.1 GA running on JDK6. It worked flawlessly. Thank you for the example.

Cheers!!!

 
Software