Skip to content

REST with JAX-RS and silverlight clients

I am Working on a RESTful  service using Jersey (not my first choice, but a reasonable compromise). It is hosted inside FuseESBand all is well. Here’s an overly simplified version of the resource that reports status:

  1. @Path("/stat")
  2. public class StatusResource {
  3.     @GET
  4.     @Produces(MediaType.TEXT_PLAIN)
  5.       public String getStatus() {
  6.         if (checkStatus())
  7.             return "Ok";
  8.          else
  9.             return "Not so good";
  10.     }
  11. }

Then we tried to connect a silverlight client to this server (don’t ask me why).  The first hurdle was a security one. Silverlight doesn’t like to communicate with a server it didn’t launch from. To resolve that you need to add a ClientAccessPolicy.xml to the root of your domainto allow cross-domain access. Here’s a simple all-permissive version of it:

  1. @Path("clientaccesspolicy.xml")
  2. public class ClientAccessPolicyResource {
  3.     @GET
  4.     @Produces(MediaType.APPLICATION_XML)
  5.     public String getStatus() {
  6.         return "<?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 path=\"/\" include-subpaths=\"true\"/>"+
  7.      " </grant-to></policy><policy ><allow-from http-methods=\"*\"><domain uri=\"*\"/></allow-from><grant-to>"+
  8.       "<resource path=\"/\" include-subpaths=\"true\"/> </grant-to></policy></cross-domain-access></access-policy>";
  9.     }
  10.  
  11. }

By the way – since silverlight is entirely a client technology you can also serve it from the Java web server (as long as you emit the right mime-type ) in which case you don’t need the cross-domain policy mentioned above.

Another interesting phenomena we saw was that the client only got the response once. no matter how many times we polled the server. We ran fiddler and saw that no request are in fact going out to the server – it was the browser’s (IE8) cache that was holding us back. It took me some head scratching as to how to solve this – but the solution is pretty simple – return an ‘expires” http header from the server to make sure the browser will only cache the result for a limited time. To do that with jersey you need to return a Response object instead of the text (or JSON/HTML etc.)

  1. @Path("stat")
  2. public class StatusResource {
  3.  
  4.     @GET @Produces(MediaType.TEXT_PLAIN)
  5.     public Response getStatus() {
  6.  
  7.         Response.ResponseBuilder response = Response.ok(checkStatus);
  8.  
  9.     Date expirationDate = new Date(System.currentTimeMillis() + maxCacheInterval);
  10.     response.expires(expirationDate);
  11.      return response.build();
  12.     }
  13.  
  14. }

While I think Silverlight is a technology on its way out. It is still around. It is nice to know that with a couple of simple moves you can get it to play nice even with a Java backend


Illustration by arinas74

Published inBlog