Mariusz has posted 1 posts at DZone. View Full User Profile

An Account of Developing a Hybrid Java/Flex Application

09.05.2008
| 35300 views |
  • submit to reddit

Using a Web Service in Flex

To be able to make use of a web service in Flex we'll need to utilize the <mx:WebService> component. What we will also need is the URL to our web service. Where do you get the URL from? Assuming you did the Java part, you can get the URL from the table when you test the web service in NetBeans. It should look something like this: 'http://localhost:8084/JPedalServer/PDFImage?wsdl'. OK, now for some code:

<mx:WebService id="ws" wsdl="http://localhost:8084/JPedalServer/PDFImage?wsdl"
fault="handleFirstStartFault(event)"
result="handleFirstStartResult(event)"/>
<mx:Script>
    <![CDATA[
    // some code omitted
    private function handleFirstStartFault(event:FaultEvent):void {
           // executed when something goes wrong
          Alert.show(event.fault.faultString);
    }
    private function handleFirstStartResult(event:ResultEvent):void {
           // executed when the web service returns a result
    }
    private function doStuff(): void {
            // call the firstStart method of the web service
           ws.firstStart("test.pdf");
    }
    ]]>
</mx:Script>

OK, we'll start off with some concepts. The <mx:WebService> component has a result handler and a fault handler. The result handler is executed when the web service finishes and returns a value. The fault result is triggered when something goes wrong, the server is not accessible or there was and error in our Java code on the server. The handleFirstStartResult(event) gets a ResultEvent type object passed in a parameter. That object is a type of a wrapper which encapsulates the result (event.result) of the web service operation as well as other aspects of the web operation, which we are not interested in at the moment. The situation looks similar in case of the handleFristStartFault(event) function. The main difference here is that we have a falult object instead of a result one (event.fault).

To actually call one of the web service operations we have to first make sure we give our <mx:WebService> component an id. In my case it is “ws”. Using the id we can refer to our component in AS3 code, just like I do in the doStuff() function which is assigned as a click listener on our button. The important thing here is that auto completion will not show us any of the web service operations. We just have to type the name of the operation we want to use, and pass it the correct parameters (if any). If we miss spell the operation name or pass in incorrect parameters the fault handler of the web service component will be triggered. For the purpose of simplicity I assumed that there is a file, called test.pdf, already in the correct place on the server, when doStuff() is executed.

So how do you actually get the data from the result object?

private function handleFirstStartResult(event:ResultEvent):void {
    // executed when the web service returns a result
    var a:ArrayCollection = event.result as ArrayCollection;
    // if return type was say String ten
    // var s:String = event.result as String;
    var imageName:String = ObjectUtil.toString(a.getItemAt(0));
    // get rid of the quote marks
    imageName = imageName.substring(1,imageName.length-1);
    // drop the '.png'
    dir = uploadFileName.substring(0,uploadFileName.length-4);
    img.source = serverPath + "Flex/Img/"+ dir+ "/"+ imageName;
    // here we handle the number of pages
    var numberOfPages:String = ObjectUtil.toString(a.getItemAt(1));
    var lenght:int = numberOfPages.length;
    numberOfPages = numberOfPages.substring(1,lenght-1);
    // maxPages is a global var in the Flex app
    this.maxPages = parseInt(numberOfPages);
}
If you remember the web service operation firstStart(String) returns a two element string array. I chose to return values in such way for the purpose of this tutorial. Looking at the above code we can see that in order to cast the result object in to a generic ArrayCollection object we use the key word as. If the type was say String we would have just used event.result as String. We can access elements in the ArrayCollection object using the getItemAt(int) method. If we know that a particular item is a String we can turn it in to one using ObjectUtil.toString(Object). If it is a number we can use parseInt(String) or parseFloat(String). One last thing about the above code. You probably noticed I'm stripping the first and last character of the strings I get from the web service. That is because when you get a String from the Java side it includes the String quote marks.

Uploading Files in Flex


This section ties in with the Java section on uploading files. Uploading files to a server in flex requires two things to be present on a server. The crossdomain.xml and a upload script. Both of there file have their own sections in the Java part of the tutorial. On the flex side we'll be making use of the FileReference object. That object has two very important methods: browse(FileFilter) and upload(URLRequest).

When the browse(FileFilter) method is executed a system file chooser dialog window is open. The user then has a chance to select the desired file. The method can also be called without a FileFilter as a parameter. If that occurs the user can select a file of any type. After the selection is made a reference to the selected file is created, and can later be referred to.

Before using the upload(URLRequest) method, we need to specify a URLRequest object.

var request:URLRequest = new URLRequest("http://localhost:8084/JPedalServer/fileUpload.jsp");
request.method = URLRequestMethod.POST;

It is here that we make use of the upload script we prepared before. We pass the path to the script in the constructor of the URLRequest object and later set the method property to POST, which basically means that the data will be transmitted with the URLRequest object with the HTTP POST method. When everything is ready and ..upload(request) will be executed, the flex application will communicate the the Java Web Service. The crossdomain.xml will be looked up. If communication is allowed the data will be transmitted to the server. There the upload script will intercept the request object and write the data to the file system in whatever way the user define it.

var fr:FileReference = null;

public function browse():void {
   fr = new FileReference();
   var pdfFileter:FileFilter = new FileFilter("Pdf Files","*.pdf");
   fr.browse([pdfFileter]);
}

private function upload():void {
    var request:URLRequest = new URLRequest("http://localhost:8084/JPedalServer/fileUpload.jsp")
    request.method = URLRequestMethod.POST;
    fr.upload(request);
}
 

Final version of the mock up viewer

Final version of the Viewer project

Using a Standalone Version of Tomcat

Some of you may want to use the standalone version of the Tomcat server, instead of the one which comes bundled with NetBeans. There should be no issues with doing so as long as you will remember to edit the source files so they refer to the port 8080 (default Tomcat port) instead of 8084 (if used through NetBeans).

What Next?

At this stage you have all the code you need to run the application. The mock up viewer uses only some of the functionality of the web service. A bit more work has to go into data presentation as well. You can view the source of the Flex Viewer to see I did the image rotation, zooming and all the rest. All the source files (Java and Flex) have comments in them and hopefully explain clearly how things work. Any questions or suggestions are welcome, don't hesitate to email me (mariusz AT idrsolutions DOT com)!

AttachmentSize
tutorial_html_2e51c903.jpg44.67 KB
tutorial_html_4d0d1668.jpg54.26 KB
tutorial_html_5717e36d.png9.22 KB
tutorial_html_4439460e.png12.88 KB
tutorial_html_m36babc34.gif28.69 KB
tutorial_html_m62eed3d8.png10.66 KB
tutorial_html_m9807edd.jpg41.49 KB
tutorial_html_m38373e52.jpg27.05 KB
tutorial_html_m9768552.png14.54 KB
flex-pdf-viewer.png67.61 KB
PDFImage.java3.62 KB
fileUpload.txt1.63 KB
crossdomain.txt298 bytes
Published at DZone with permission of its author, Mariusz Saternus.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Brian Matzon replied on Mon, 2008/09/08 - 3:11am

It broke my back button ;)

This looks more like a component description thana breakdown on what went well and what didn't.

Why go for flex ? - why not an applet?

Why use java as backend ?

Mariusz Saternus replied on Mon, 2008/09/08 - 4:14am

The reason for not using an applet is because I wanted to avoid a Java dependency on the client in this case - I wanted to use Flex.

If you have an Flex RIA and you want to say display a pdf file you just generated to the user you can't just use an applet. There is no way Flex will be able to 'talk' to the applet. That is what I was interested in - finding ways of communicating between the two technologies. 

The reason for using Java ... well I'm a Java programmer so the choice was obvious. Java is one possible option which may or may not suit everyone.

The article was never meant to be a "breakdown on what went well and what didn't". When I was working on the project I found it hard to find information about the things that I was working on and I wanted to share my findings with others.

Srinivas Veeravalli replied on Tue, 2008/09/09 - 12:27am in response to: Mariusz Saternus

Flex and Java applets can be used in a mixed environment. There are, however, challenges:

  • Making the applet visible. You can do this with a floating iframe, and with the applet as the source of the iframe. You need to set wmode to opaque in Flex for the iframe (and applet) to appear. Else they will go underneath the Flex rectangular area, and will never be visible.
  • Once you achieve the above, there are still z-ordering issues. Essentially the applet will "eat up" all Flex-based visual entities (mouse gestures,Flex dialogs, etc) which overlap with the applet area. There are ways to work around this problem, but these are not very pretty.
  • Finally the communication: you can use JScript (on the Java side) and ExternalInterface (on the Flex side). The glue would of course be JS functions.
So it can be done. Question is whether it is aesthetic enough.

Mariusz Saternus replied on Tue, 2008/09/09 - 12:59am in response to: Srinivas Veeravalli

Thanks for the info. I wasn't aware of such possibilities. There would still be one problem though, what it the users has disabled JS ? Cheers!

Srinivas Veeravalli replied on Tue, 2008/09/09 - 2:59am in response to: Mariusz Saternus

Hmmm.. how would your Flex program run then? AC_OETags.js ring a bell?

 Cheers :-)

Srinivas Veeravalli replied on Tue, 2008/09/09 - 3:02am in response to: Srinivas Veeravalli

Sorry, you are right - it is possible to run Flash without JS.

 But JS presence is a valid assumption in today's Ajax world, I suppose...

 Peace.

Dario Herrera replied on Mon, 2008/09/15 - 6:13am

take a look of Fiji: Exadel Fiji extends JSF by allowing the use of Flex with JSF components and within a JSF page....

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.