To better demonstrate how to generate XML RSS 2 feeds, we will use a servlet with JDOM 2 library. In this short blog, we will generate only the
required elements plus a few options for feed reader interoperability. Please refer to the RSS 2 documentation for more of the optional elements and
to learn more about the RSS 2 specifications. JDOM 2 is available for download here http://www.jdom.org/.
Below is a sample RSS 2 feed generated by the servlet that follows further down (contents edited for clarity).
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<!-- title, link, description are required -->
<title>Primo's code blogs feeds</title>
<description>Feeds from Kahimyang Projects Primo's code blogs</description>
<link>http://kahimyang.info/kauswagan/RssFeeds.xml?type=howto</link>
<language>en</language>
<!-- Only for feed reader interoperability -->
<atom:link rel="self" href="http://kahimyang.info/kauswagan/RssFeeds.xml?type=howto"
type="application/rss+xml" />
<!-- Contents of the feed -->
<item>
<title>
Title of the story item.
</title>
<link>
URL that points to the full content.
</link>
<description>
<![CDATA[
Description of the item. In the case of a blog or
news item, this can be the synopsis.
]]>
</description>
<guid>
unique_id_of_the_feed_item
</guid>
<!-- Required format. Publication date -->
<pubDate>Fri, 16 Sep 2011 14:31:01 EDT</pubDate>
</item>
<!-- more items -->
</channel>
</rss>
The sample feed above was generated based on the recommendation of the Feed Validator Service from w3.org.
Elements <link /> and <atom:link /> in lines 7 and 11 should point to the URL of the feed. Sub-element <link /> of <item /> points to the URL of the item itself. Date and time values should conform to RFC #822. Wrapping the description with CDATA is required if the content has HTML formatting.
Here is the servlet that generated the above sample feed. Please refer to the inline comments for more information. In this servlet,
items are drawn from a database. Please note that some lines were removed for clarity.
package pname;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jdom2.CDATA;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
@WebServlet(name = "RssFeeds", urlPatterns = {"/RssFeeds.xml"})
public class RssFeeds extends HttpServlet {
@Override
protected void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/xml;charset=UTF-8");
PrintWriter servlet = response.getWriter();
try {
// Create the root rss element
Element rssRoot = new Element("rss");
// Required attribute
rssRoot.setAttribute("version", "2.0");
// Create the XML document
Document feed = new Document();
feed.setRootElement(rssRoot);
Element channel = new Element("channel");
rssRoot.addContent(channel);
channel.addContent(new Element("title").
addContent("Title of the Feed"));
channel.addContent(new Element("description").
addContent("Description of the entire feed"));
final String url=
"http://kahimyang.info/kauswagan/RssFeeds.xml?type=howto";
channel.addContent(new Element ("link").addContent (url));
channel.addContent(new Element("language").addContent("en"));
// Create the atom namespace
Namespace atom =
Namespace.getNamespace("atom","http://www.w3.org/2005/Atom");
rssRoot.addNamespaceDeclaration(atom);
Element link = new Element ("link",atom); // atom:link
link.setAttribute("rel","self").setAttribute("href",url).
setAttribute("type","application/rss+xml");
channel.addContent(link);
addRssItems (channel); // the actual feeds
// Write the document to the servlet response
XMLOutputter output = new XMLOutputter();
output.setFormat(Format.getPrettyFormat().setEncoding("UTF-8"));
output.output(feed, servlet);
}
finally {
servlet.flush();
servlet.close();
}
}
void addRssItems (Element channel) {
// Build the query
StringBuilder q = new StringBuilder("select ...");
try (
// Change the way you connect to database.
Connection conn = DatasourceConnection.getConnection();
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery(q.toString())) {
while (result.next()) {
Element item = new Element("item");
item.addContent(new Element("title").
addContent(result.getString(1)));
// link to the item itself
item.addContent(new Element("link").
addContent(result.getString(2)));
// This can be a sysnopsis
// Strip off risky attributes from html tags
String teaser=Jsoup.clean(result.getString(3),Whitelist.basic());
item.addContent(new Element("description").
addContent(new CDATA(teaser)));
// Unique ID, usually this is the same as link
item.addContent(new Element("guid").addContent("the_unique_id"));
// Required format
SimpleDateFormat f =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
item.addContent(new Element("pubDate").
addContent(f.format(result.getTimestamp(4))));
channel.addContent(item);
}
} catch (Exception e) {
// return an empty channel
}
}
@Override
public String getServletInfo() {
return "Short description";
}
}
Character encoding specified in lines 30 and 77 should match. Application type application/xml should also be used for some browsers to render the feed correctly.
Additional library used in this servlet (line 112 above) is Jsoup. It can be downloaded here http://jsoup.org/.
That's it Good Luck.