Go to content

Generate RSS in JSP? Set the locale!

Published on

The RSS pubDate fields contain dates in a format that may be human readable, but not very handy in a programmer’s point of view. According to the RSS specification the date must conform to the RFC822 specification. A typical RSS snippet looks like:

<item>
  <title>Generate RSS in JSP? Set the locale!</title>
  <description><p>Description of the feed item</p></description>
  <link>http://blog.jasha.eu/2009/12/generate-rss-in-jsp-set-locale.html</link>
  <guid>http://blog.jasha.eu/2009/12/generate-rss-in-jsp-set-locale.html</guid>
  <pubDate>Wed, 10 Dec 2009 09:55:00 +0100</pubDate>
</item>

A way to format a java.util.Date in JSP is using the fmt library from JSTL.

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<item>
  <title>${item.title}</title>
  <description>
    <![CDATA[<hst:html hippohtml="${item.html}"/>]]>
  </description>
  <link>${link}</link>
  <guid>${link}</guid>
  <pubDate>
    <fmt:formatDate value="${item.date.time}" 
                    pattern="EE, dd MMM yyyy HH:mm:ss Z"/>
  </pubDate>
</item>

This seems to look good when you request the RSS feed from your browser. However when you request the same feed from a Java (ROME), a request generator (Fiddler) or just use wget the format of the pubDate field is invalid. It returns Wed Dec 10 09:55:00 CET 2009 instead of Wed, 10 Dec 2009 09:55:00 +0100 as value of pubDate. What happened?

Your browser sends a header Accept-Language with, hopefully, en-US as first value. The JSTL library uses the en-US locale to format the date and the feed gets parsed correctly. The other tools don’t send this header and the programmer did not specify a locale for fmt. fmt does not know how to format the date and returns a Date.getString();.

A workaround for you as requester of the feed is to manually add the "Accept-Language" header to the request with value en-US. For the JSP developer: the date format for RSS should always be en_US. Just add this line to your JSP:

<fmt:setLocale value="en_US"/>