Making resource request from portlet using Flex application

I built this sample portlet in which i am making a resource request to the portlet. My portlet is very simple the doView() method returns HTML that includes a Flex application and then the flex application makes HTTP call to the portlet.

The interesting part was since the portlets are not URL addressable i cant hard code the resource URL inside my flex application so what i did is i am generating the resource URLs on the HTML and then making use of Flex to JavaScript communication capability to first get the Resource URL and then the FLex application was making HTTP call using action script. This is how my demo portlet looks like, you can download the sample code from here

  1. HelloFlex.zip- Flex source code

  2. FlexPortlet.war - Portlet Source code





I followed these steps to build the demo application


  • First create a FlexPortlet.java file like this, as you can see in the doView() method of the portlet i am passing control to the flex.jsp and in the serveResource() method i am returning "Returning response from FlexPortlet.serveResource" message.


    package com.webspherenotes.flex;

    import java.io.IOException;
    import javax.portlet.ActionRequest;
    import javax.portlet.ActionResponse;
    import javax.portlet.GenericPortlet;
    import javax.portlet.PortletException;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    import javax.portlet.ResourceRequest;
    import javax.portlet.ResourceResponse;

    public class FlexPortlet extends GenericPortlet {
    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    response.setContentType("text/html");
    getPortletContext().getRequestDispatcher("/flex.jsp").include(request, response);
    System.out.println("Exiting FlexPortlet.doView()");
    }
    public void serveResource(ResourceRequest request, ResourceResponse response)
    throws PortletException, IOException {
    System.out.println("Entering FlexPortlet.serveResource()");
    response.setContentType("text/html");
    response.getWriter().println("Returning response from FlexPortlet.serveResource");
    System.out.println("Exiting FlexPortlet.serveResource()");
    }
    }




  • This how the flex.jsp code looks like

    <%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.1/portlet-client-model" prefix="portlet-client-model"%>
    <%@taglib uri="http://java.sun.com/portlet" prefix="portletx"%>
    <portletx:defineObjects />
    <script type="text/javascript">
    function getResourceURL(){
    console.log("Returning resourceURL");
    return "<%=renderResponse.createResourceURL().toString()%>";
    }
    </script>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
    id="HelloWorld" width="100%" height="100%"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
    <param name="movie" value='<%= renderResponse.encodeURL(renderRequest.getContextPath() + "/HelloWorld.swf") %>' />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#869ca7" />
    <param name="allowScriptAccess" value="sameDomain" />
    <embed src="<%= renderResponse.encodeURL(renderRequest.getContextPath() + "/HelloFlex.swf") %>" quality="high" bgcolor="#869ca7"
    width="100%" height="100%" name="HelloWorld" align="middle" play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
    type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer">
    </embed>
    </object>

    The JSP code is pretty simple it has a getResourceURL() javascript method that will be called by Flex application and it is including HelloFlex.swf in the markup.


  • The biggest chunk of business logic is in the HelloFlex.mxml, this is how it looks like, please note that i am not Flex expert and i believe a Flex expert might be able to build much better code here. In my case both application layout and business logic is in the same file

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    width="100%" height="100%" >
    <mx:Script>
    <![CDATA[
    import flash.external.*;
    import mx.controls.Alert;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.http.HTTPService;

    //Event handler for handling button click
    public function getPortletResponse():void
    {
    var javaScriptMethodName:String = "getResourceURL";
    if (ExternalInterface.available) {
    // Make call to the getResourceUrl javaScript function
    var portletUrl:String = ExternalInterface.call(javaScriptMethodName);
    useHttpService(portletUrl);
    } else
    displayText.text = "Error sending data!";
    }
    //This method is used for making a URL call
    private var service:HTTPService
    public function useHttpService(url:String):void {
    service = new HTTPService();
    service.url = url;
    service.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
    service.method = "GET";
    service.addEventListener("result", httpResult);
    service.addEventListener("fault", httpFault);
    service.send(parameters);
    }
    //This callback gets called in case if the http response is returned
    public function httpResult(event:ResultEvent):void {
    var result:Object = event.result;
    displayText.text = event.result.toString();
    }
    //This call back gets called in case of error in http request
    public function httpFault(event:FaultEvent):void {
    var faultstring:String = event.fault.faultString;
    displayText.text = event.fault.faultDetail;
    Alert.show(faultstring + event.fault.faultDetail + event.fault.rootCause);
    }
    ]]>
    </mx:Script>
    <mx:Panel id="pnlMain" x="333" y="10" width="514" height="144" layout="absolute" title="Serve Resource Example">
    <mx:Button label="Make Resource request" y= "75" id="resourceUrl" click="getPortletResponse()" x="10"/>
    <mx:TextArea x="10" y="10" width="493" height="61" id="displayText"/>
    </mx:Panel>
    </mx:Application>

    My application layout is pretty simple it has a button and a Text Area, when we click on button the control gets passed to getPortletResponse() method and that method will take the output generated by the portlet and write it in the text area.

    The getPortletResponse() method is calling the getResourceURL() javascript function by using ExternalInterface ExternalInterface.call(javaScriptMethodName); like this, the getResourceUrl() method will return the resourceUrl generated by the RenderResponse.createResourceURL() method and then it is passing the control to useHttpService() method.

    The useHttpService() method is making HTTP "GET" call to the resourceUrl and then it is attaching the httpResult() function as a callback function for the ajax request the httpFault() method gets called in case of error in HTTP call.

No comments: