October 2010 Archives

Amazon's SQS (Simple Queue Service) uses XML formatted payloads to push and pop messages to and from an SQS queue.  In other words, the underlying request and response bodies are XML payloads, containing among other things, a message ID and a message receipt handle.  This means that the message body itself (the thing you're pushing onto the queue) ultimately has to be properly XML escaped to work right.  Well it turns out, Amazon's own AWS library is very flaky here, and does not do the right thing when unmarshalling an XML SQS response back into an Object.  Essentially, it gets confused when it encounters an XML escaped ampersand in the message body.  For example, this popped message (in pseudo XML) fails miserably to unmarshall:

<sqs><message>{"music":"rock &amp; roll"}</message></sqs>

Note that the ampersand in the message body is properly XML escaped, however, Amazon's own AWS library returns this as the message body once unmarshalled:

{"music":"rock &

In other words, the message body ends abruptly at the ampersand, and needless to say, any reasonable JSON library will fail to parse this malformed block of nonsense.

Solution: if you are going to use SQS, and there's a possibility the messages you're going to push onto a queue will have issues with XML escaping, it appears you should always base-64 encode the message body, then base-64 decode it when popping.  Fortunately, the Apache Commons Codec library has a wonderful Base64 class to handle this encoding and decoding mess for you.

Bottom line, if you're encountering encoding issues with Amazon's SQS, better check if your messages are able to make it through the XML marshalling and unmarshalling process.  If not, you'll need to base-64 encode and decode your messages to dance around bugs in Amazon's AWS library.

Good luck, and hope this helps.
The other day on some Java/JSP tutorial web-site I saw the worst example ever for detecting and properly rendering a mobile capable version of a web-site.  Yes, I'm pointing at you Roseindia.  In every JSP of this example, their mobile User-Agent detection involved one big if/else block:

<%

String userAgent = request.getHeader("User-Agent");
if(userAgent.contains("iPhone")) {
%> Mobile site! <%
} else {
%> Regular site! <%
}

%>

This wins the worst coding example of the year award.  Here's why this is terrible and you should never use this example:

  1. Not all requests contain a User-Agent header.  In fact, the User-Agent header is purely optional.  In the code above, if the request does not contain a User-Agent you'll see a nice NullPointerException thrown at userAgent.contains() given that the userAgent is null.

  2. Not every mobile device is an iPhone.  What about Blackberry, Andriod or Palm clients?  Blindly assuming that every mobile user is on an iPhone, or other similar device, is horrendously ignorant.

  3. Many great frameworks exist, like Spring 3 MVC, that allow you to separate your web-application business and display logic.  This in mind, combing both into a single JSP is a bad idea for a number of reasons.  In an ideal world, your mobile device detection would occur in an interceptor that triggers your MVC framework to render one view for mobile devices, and another view for all others.

This is a fairly common requirement: users visiting your site in a standard web-browser see one view, and users on a mobile device (like a Palm) see a "mobile version" of the same view.  So, here's a way to implement better mobile device detection in your web-application using a Spring 3 HandlerInterceptorAdapter ...

Twitter (@markkolich)

Translate

About this Archive

This page is an archive of entries from October 2010 listed from newest to oldest.

September 2010 is the previous archive.

December 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.