How-To : Silverlight accessing Java REST services (Part 1 - Cross Domain : IIS + Tomcat)

The HowTo serie demoes Silverlight accessing Web Services in various configurations. In this post, we will demonstrate a REST service consumed by HTTP GET and POST requests issued from a Silverlight client application. This scenario can be categorized as a D2D scenario with a cross domain policy.

The Silverlight example described below is available as an attachment to this post.

Technical environment

  • REST services are built with Restlet and hosted in Tomcat
  • The Silverlight application is hosted under the Visual Studio embedded Web Server code name "Catalina" (which delivers a subset of the IIS capabilities)

image

Because the Site of Origin and the Web Services reside in different hosts, a Cross Domain policy is required at the Services host’s root (/clientaccesspolicy.xml">https://<serviceshostname:port>/clientaccesspolicy.xml)

Implementation of the REST service

To get an overview of the Restlet framework, complete the tutorials : First Steps and First Resource.

Service development with Restlet can be summarized as follow :

  • The Application class is the entry point to the Restlet service. It  binds a URI to a specific Resource.
  • The Resource class describes how the service behaves on a specific URI invokation.

After completing the tutorials above, deploy the firstResource service as a Servlet hosted by Tomcat.

Invoke the Restlet service with the URI https://localhost:8080/Restlet-servletfirstResource/items. Assuming that Tomcat is running on port 8080 and that your Restlet project name is Restlet-servletfirstResource, you get the following response :

   <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
   <items>
      <item>
         <name>item1</name> 
         <description>description of item1</description> 
      </item>
    </items>

Enabling Cross Domain Access

Since the REST service and the Silverlight application are hosted in different hosts, we need to overpass the Cross Domain Issue. Create at the root of the REST service host, a clientaccesspolicy.xml file with the following content :

 <?xml version="1.0" encoding="UTF-8"?>
 <access-policy>
     <cross-domain-access>
         <policy>
             <allow-from http-request-headers="*">
                 <domain uri="*"/>
             </allow-from>
             <grant-to>
                 <resource include-subpaths="true" path="/"/>
             </grant-to>
         </policy>
     </cross-domain-access>
 </access-policy>

 

Consuming a REST service with Silverlight (GET method)  

We chose the WebClient API to request the REST service, and LINQ to process the XML response. XmlReader is another parsing option, and Serialization (Xml or DataContract) is another one.

Invocation of the REST service

First of all, in your UserControl, declare a MyItem class that will map the XML response elements.

    1:  public class MyItem
    2:  {
    3:      public string myName { get; set; }
    4:      public string myDescription { get; set; }
    5:  }

 

    1:  // List of Items
    2:  IEnumerable<MyItem> Items = null;

Now, let's send a HTTP GET method request to /items URI so we can retrieve every items

    1:  private void getAction()
    2:  {
    3:      WebClient webclient = new WebClient();
    4:      webclient.DownloadStringCompleted += 
    5:        new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
    6:      webclient.DownloadStringAsync(new Uri("https://localhost:8080/Restlet-servletfirstResource/items"));
    7:  }

Processing the XML results

Let’s process the results using LINQ support for XML :

    1:  void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    2:  {
    3:      if (e.Error == null)
    4:      {
    5:          XDocument xmlItems = XDocument.Parse(e.Result);
    6:          // use LINQ to XML to parse the response
    7:          Items = from child in xmlItems.Element("items").Descendants().ToList()
    8:                  // restrict the selection to item children
    9:                  where child.Name.LocalName=="item"    
   10:                  select new MyItem
   11:                      {
   12:                          myName = (string)child.Element("name"),
   13:                          myDescription = (string) child.Element("description")
   14:                      };
   15:      } 
   16:  }

Sending Data to a REST service with Silverlight (POST method)

Use the WebClient to send a HTTP POST request to the /items URI, by adding two parameters : name = "Foo"  and description = "Bar" :

    1:  private void postWebClient()
    2:  {
    3:      WebClient webclient = new WebClient();
    4:      webclient.UploadStringAsync(
    7:        new Uri("https://localhost:8080/Restlet-servletfirstResource/items"),
    8:        "name=Foo&description=Bar"
    9:      );
   10:  }

 

Warning : Notice that if you try to hit the same URI several time with the HTTP GET method, the results do not get refreshed but remain the same. Further explanations about this caching issue are available here.

 

- Ronny Kwon

REST Service in Tomcat + Silverlight Client - Cross Domain .zip