IntroductionThis is a guide that helps you fit a Flex front end for your existing Struts application using FxStruts. An important thing to keep in mind is that the Flex application is the one going to be in control and is going to treat the Struts backend as a service. All the control redirection done on the Struts side only affects what data the Flex side receives. One of the key advantages of FxStruts is that you can change the frontend to Flex without changing your Struts Action classes. Of course, if you use transaction tokens in your Action class so that class A has to be visited before class B, then the Flex side will simply have to hit two classes. In such a case, you would be better off changing the code in the Action class. DetailsFirst, examine your struts-config.xml file to study the JSPs that are currently in use.Example: <action
path="/SubmitLogon"
type="org.apache.struts.apps.mailreader.actions.LogonAction"
name="LogonForm"
scope="request"
cancellable="true"
validate="true"
input="Logon">
<forward
name="Success"
path="/MainMenu.jsp"/>
</action>Here a request to /SubmitLogon.do executes the LogonAction class and if that Action class returns Success, control will flow to MainMenu.jsp. For each JSP, isolate only the data coming in over from the Action class.MainMenu.jsp: <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<html><head><title>Sample</title></head>
<body><p>Value of SomeBean:</p>
<input type="text" value="<bean:write name='somebean' />"
</body>
</html> Here, there is a Struts <bean:write /> tag accessing a Java object set in the Action class. That is the bit we are interested in. Create new JSPs that use FxStruts taglib fx:write to output that data.In the new JSP use the fx:write with name and property set to the same values as that in the original JSP. Now the Flex side can access this data by hitting your .do URL (/SubmitLogon.do in this case). Note: fx:message is the equivalent of bean:message but it also supports "errors" and "token". MainMenuAMF.jsp: <%@ taglib uri="/WEB-INF/lib/fxstruts.jar" prefix="fx" %><fx:write name="somebean" type="amf" /> Unlike the bean:write tag, with fx:write you can pass complex Java objects and these objects will be recieved with types preserved on the Flex side. You might also want to set the errors attribute of fx:write to true if there was an <html:errors/> tag in the original JSP. With errors set to true, you get the errors message nested within the result object along with the result. If the Action class uses a transaction token, you can set token attribute to true to have the value of the transaction token nested along with the actual result in the result object. This value has to be subsequently re-sent in the next HTTPAMFService request so that Struts is assured that the transaction is valid. Note: If there are multiple bean:write tags and each are accessing different properties of the same object, output that object using fx:write. Avoid multiple fx:write tags as this will introduce a dependency on the Flex side where the Flex side component has to know exactly how many AMF objects are coming in. (This is done by setting the numObjects property of HTTPAMFService) Change the mapping in struts-config.xml to point to the new JSPs.You could either create a new Action mapping or change the existing one and swap config files when you want the HTML version. Changed struts-config.xml: <action
path="/SubmitLogon"
type="org.apache.struts.apps.mailreader.actions.LogonAction"
name="LogonForm"
scope="request"
cancellable="true"
validate="true"
input="Failure">
<forward
name="Success"
path="/MainMenuAMF.jsp"/>
<forward
name="Failure"
path="/MainMenuFailAMF.jsp"/>
</action>Now we create our Flex frontend- Create a new Flex Project in Flex builder that links to HTTPAMFService.swc.
- Create the necessary view controls in your Flex application.
- Use the HTTPAMFService tag to let the Flex application communicate with your Struts backend.
- Call HTTPAMFService's send() function with parameters that you would normally pass to the web object.
Example: service.send({option:1,name: "test"})The result handler will be called with the value returned by our new JSP. Use the result to determine the view state and change the data displayed in your Flex controls.
|
It would be more helpful if this tutorial did not have a prerequisite for a tool that costs money. Even though that is not the crux of the article/tutorial, it would make it more accessible to your audience.
How does one link a swc to a flex project outside of Flexbuilder is the question?
Hi Dan,
Just read up on how to use mxmlc. You can pass in options to mxmlc either via command line arguments or via an XML file. The option to keep in mind for linking in swcs is library-path.
Hi, Sending params from java/struts to a flex application is not a really big issue and can be simulated easily with xml and E4X result format. The real issue I’m struggling with is sending params from flex to a not-so-small ActionForm?. For instance I would have a SaveForm? which has a property of type Person which in turn has a property of type Address and I want to populate the street number. I’ve seen some examples of re-declaring a java class into AS3 and adding the metadata RemoteClass?=”com.SomeClass?”, but this would expose the structure of the JavaBeans? into the frontend. Which I don’t want. Is it possible? If so, could you post an example of that?
PS for Dan: there are some so called flex ant tasks which you can take into eclipse and use to compile and generate HTML wrappers. Take a look: livedocs.adobe.com/flex/3/html/anttasks_1.html
Hi Andy,
FxStruts? does not convert data sent from Flex to AMF. It relies on HTTPService's send({as3objecthere}) mechanism which takes in an AS3 Object and uses its key value pair as the form's key value pair.
I don't think this mechanism will work for strongly typed objects as internally it does a "for in" over the object. It has to be of type Object. So if you simply define an object to match the fields of your SaveForm?:
var saveform:Object = {field1: value1, field2, value2}
It will work.
Hi, I tried your suggestion a long time ago but for some reason it didn't work for me. I just doesn't send the request. I've seen this on other parts, the AS doesn't throw any exceptions and doesn't post any errors. It just freezes. Your solution wouldn't work if your field1 is in the form: person.address.streatNo.
I found another way you can do the submit, which actually worked everywhere in all of my projects. I'll post it here if anybody stumbles into the same problem. Based on previous example, you can do something like this:
var params:Object = {}; params["person.address.streatNo"] = streatNo.text; service.send(params);
Assuming streatNo is a text field.
Hi andykutkh,
You are right, my solution wouldn't work if field1 has dots in them. Using the square bracket syntax would work around that.
Hi andykutkh,, How to connect between stuts and flex application?
Hello anirudhsasikumar, First Thank you for the articles and material on Flex and Struts integration. This helped me much. Also article on Cairngorm Architechture. Though I am facing a small problem while apssing ArrayCollection? to my backend. I have an ArrayCollection? which in turn has some other BOs. Now I can fetch such arracycollection from the backend and its working great. But it does not work the other way i.e., when i try to send an nested arraycollection (as mentioned above) the call simply fails. Also i have tried this for a simple arraycollection containing string and plain objects. I have also checked for the case of the variables in the BOs(which usually can be a problem as it is case sensitive!). Please let me know if you have any idea on how to pass an arraycollection to the java code at the backend?
FxStruts? only handles AMF in one direction: From java to Flex. The other way round requires some glue writing (a servlet that reads AMF and converts to POJO). The AMF support is there; but the glue servlet has to be written.