5
votes

I need a way of getting the active server address, port, and context during runtime from my flex application. Since we are using ant for our build process, the server connection information is dynamically specified in our build properties file, and the {server.name}, {server.port} and {context.root} placeholders are used in the services-config.xml file instead the actual values.

We have some other Java servlets running on the same machine as our blazeDS server, and I'd like some way to programmatically determine the server endpoint information so I don't need to hardcode the servlet URL's into an XML file (which is what we are presently doing).

I have found that I can at least get the context root by adding the following to our main application MXML file:

<mx:Application ... >
  <mx:HTTPService id="contextRoot" rootURL="@ContextRoot()"/>
</mx:Application>

However, I still need some way of fetching the server address and port, and if I specify the entire address by giving -context-root=http://myserver.com:8080/mycontext, then the flex application attempts to connect to http://localhost/http://myserver.com:8080/mycontext/messagebroker/amf, which is of course totally wrong. What is the proper way to specify the context root and server URL, and how can I retrieve them from our application?

6
So are you using java servlets or just httpservice? Im not sure I am following your question exactly or what you are doing exactly, but with remote object, you can also do all of that in code instead of having to use the services-config.xml file or put it in a compiler options. Can you elaborate?Ryan Guill
We are using both. We have an HTTP endpoint, and separate Java servlets for some extra tasks. We are not using remote objects; all message handling is done through Cairngorm.Nik Reiman

6 Answers

3
votes

We use an Application subclass that offers the following methods :

 /**
  * The URI of the AMF channel endpoint. <br/>
  * Default to #rootURI + #channelEndPointContext + #this.channelEndPointPathInfo
  */
 public function get channelEndPointURI() : String
 {
    return this.rootServerURI + ( this.channelEndPointContext ? this.channelEndPointContext : "" ) + this.channelEndPointPathInfo
 }

 /**
  * The root URI (that is scheme + hierarchical part) of the server the application
  * will connect to. <br/>
  * If the application is executing locally, this is the #localServerRootURI. <br/>
  * Else it is determined from the application #url. <br/>
  */ 
 public function get rootServerURI() : String
 {
      var result : String = ""
      if ( this.url && ( this.url.indexOf("file:/") == -1 ) )
      {
           var uri : URI = new URI( this.url )
           result = uri.scheme + "://" + uri.authority + ":" + uri.port
      }
      else
      {
           result = this.localServerRootURI
      }

      return result 
 }

This generic application supports the channelEndPointContext, channelEndPointPathInfo and localServerRootURI properties (typically "mycontext" and "/messagebroker/amf/" in your example, the local server root being used when the application is executed via Flex Builder, in such cases it has a file:// URL).
The determination of the complete endpoint URI is then performed using either the localServerRootURI property or using the application url as our services are exposed by the very same server that serves the application's SWF (which is, as far as I understand your case too).

So, in your example, one would write :

 <SuperApplication ...> <!-- SuperApplication is the enhanced Application subclass -->
    <mx:HTTPService id="myHTTPService" url="{this.channelEndPointURI}"/>
 </SuperApplication>

Starting from here, one can also automatically determine the channelEndPointContext from the application URL instead of hardcoding it as shown in this example.

2
votes

I've used FlashVars to pass urls in before with success. In your template html:

var rootURL = location.href.substring(0,location.href.indexOf("flexBin"));    
...

AC_FL_RunContent(
    "src", "${swf}",
    "FlashVars", "rootURL="+rootURL,
    "width", "${width}",
...

And then in flex:

service.rootURL = Application.application.parameters.rootURL;

The nice thing is you can really pass in whatever you like from the server this way.

2
votes
var url:String = (FlexGlobals.topLevelApplication as Application).url 
            //var fullURL:String = mx.utils.URLUtil.getFullURL(url, url);

            var serverName:String = mx.utils.URLUtil.getServerNameWithPort(url);
            listContents.url = mx.utils.URLUtil.getProtocol(url)+"://"+serverName+"/custom_message.html";
            //isSecure = mx.utils.URLUtil.isHttpsURL(url);   

            //pageURL = pageURL.substring(0, pageURL.indexOf("/"));
            listContents.send();
1
votes

Why not call a javascript function in the wrapper via ExternalInterface to return the value of location.hostname?

<mx:Script>
    <![CDATA[
        private var hostname:String;

        private function getHostName():void
        {
            hostname = ExternalInterface.call(getHostName);
        }
    ]]>
</mx:Script>

javascript in wrapper:

<script type="text/javascript">
    function getHostName()
    {
        return location.hostname;
    }
</script>
1
votes

You can use the BrowserManager to get the information about the url.

var bm:IBrowserManager = BrowserManager.getInstance();
bm.init(Application.application.url);
var url:String = bm.base;

see also http://livedocs.adobe.com/flex/3/html/deep_linking_7.html#251252

1
votes

No need to do all these hard work. Just use URLUtil provided by Flex framework itself ;)