1. Getting Started
The Oorian RSS library enables you to serve RSS 2.0 feeds from your Oorian web application
entirely in Java. Extend RssFeed, annotate with @Page, and implement
a single method to build your channel. The library handles XML generation, content types,
namespace declarations, and RFC 822 date formatting.
Key Features
- Full RSS 2.0 specification support
- Built on Oorian's
HttpFileandXmlElementinfrastructure - Fluent API for building channels, items, categories, images, and enclosures
- Automatic
content:encodedandatom:linknamespace handling - Automatic HTTP response configuration (content type, encoding, and cache control)
- RFC 822 date formatting for publication dates
- Pure Java — no JavaScript or external dependencies
Library Components
| Class | Description |
|---|---|
RssFeed |
Abstract base class you extend to serve RSS feeds (extends HttpFile) |
RssChannel |
Represents the <channel> element with feed metadata and items |
RssItem |
Represents an <item> element (blog post, article, episode, etc.) |
RssCategory |
Represents a <category> element with optional domain |
RssEnclosure |
Represents an <enclosure> element for media attachments |
RssImage |
Represents the channel <image> element (logo) |
2. Project Setup
Add oorian-rss as a dependency to your Oorian web application.
The JAR must be included in your project's classpath and packaged into the deployed WAR file.
Download: Get the latest RssLib JAR from the download section of the RSS library page, available as a direct download or via Maven Central.
3. Creating a Feed
To create an RSS feed, extend RssFeed and implement the
createChannel() method. Annotate your class with @Page to map
it to a URL. RssFeed handles the HTTP content type
(application/rss+xml), XML declaration, and RSS root element automatically.
@Page("/feed")
public class BlogFeed extends RssFeed
{
@Override
protected RssChannel createChannel()
{
RssChannel channel = new RssChannel(
"My Blog",
"https://example.com",
"Latest posts from My Blog"
);
channel.addItem(new RssItem(
"Hello World",
"https://example.com/hello-world",
"My first blog post."
));
return channel;
}
}
Visiting /feed in a browser or feed reader will produce a valid RSS 2.0 XML document.
The three arguments to RssChannel are the required RSS channel elements: title,
link (your website URL), and description.
Automatic HTTP Configuration
RssFeed automatically configures the HTTP response with sensible defaults.
You do not need to set these yourself:
| Header | Value | Purpose |
|---|---|---|
Content-Type |
application/rss+xml; charset=UTF-8 |
Identifies the response as an RSS feed |
Cache-Control |
no-store |
Ensures feed readers always fetch fresh content |
If you need different caching behavior, override it in your subclass constructor
using setCacheControl():
@Page("/feed")
public class BlogFeed extends RssFeed
{
public BlogFeed()
{
setCacheControl(CacheControl.revalidate());
}
@Override
protected RssChannel createChannel()
{
// ...
}
}
Generated XML
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>My Blog</title>
<link>https://example.com</link>
<description>Latest posts from My Blog</description>
<generator>Oorian Framework</generator>
<item>
<title>Hello World</title>
<link>https://example.com/hello-world</link>
<description>My first blog post.</description>
</item>
</channel>
</rss>
4. Channel Configuration
Beyond the three required fields (title, link, description), RssChannel supports
all optional RSS 2.0 channel elements via fluent setters. The generator defaults to
"Oorian Framework" but can be changed or set to null to omit.
RssChannel channel = new RssChannel(
"Tech News",
"https://technews.example.com",
"Daily technology news and analysis"
);
channel.setLanguage("en-us")
.setCopyright("Copyright 2026 Tech News Inc.")
.setManagingEditor("editor@technews.example.com (Jane Smith)")
.setWebMaster("webmaster@technews.example.com")
.setPubDate(new Date())
.setLastBuildDate(new Date())
.setTtl(60)
.setDocs("https://www.rssboard.org/rss-specification");
Channel Options
| Method | Default | Description |
|---|---|---|
setLanguage(String) |
null |
Language code (e.g., "en-us", "fr", "de") |
setCopyright(String) |
null |
Copyright notice for channel content |
setManagingEditor(String) |
null |
Email of the content editor |
setWebMaster(String) |
null |
Email of the technical webmaster |
setPubDate(Date) |
null |
Publication date of channel content |
setLastBuildDate(Date) |
null |
Last time channel content changed |
setGenerator(String) |
"Oorian Framework" |
Program used to generate the feed |
setDocs(String) |
null |
URL to RSS format documentation |
setTtl(int) |
0 (omitted) |
Cache time in minutes before refreshing |
5. Adding Items
Items represent individual pieces of content in the feed — blog posts, news articles, podcast episodes, etc. Each item can be created with a title, link, and description, or built incrementally with the default constructor and fluent setters.
Quick Construction
channel.addItem(new RssItem(
"Breaking: New Java Release",
"https://example.com/java-release",
"Java 25 has been released with exciting new features."
));
Detailed Construction
RssItem item = new RssItem();
item.setTitle("Breaking: New Java Release")
.setLink("https://example.com/java-release")
.setDescription("Java 25 has been released with exciting new features.")
.setAuthor("editor@example.com (Jane Smith)")
.setPubDate(new Date())
.setGuid("https://example.com/java-release")
.setComments("https://example.com/java-release#comments");
channel.addItem(item);
Item Options
| Method | Description |
|---|---|
setTitle(String) |
Title of the item |
setLink(String) |
URL of the item |
setDescription(String) |
Synopsis or summary |
setAuthor(String) |
Author email (e.g., "user@example.com (Name)") |
setPubDate(Date) |
Publication date (formatted as RFC 822) |
setGuid(String) |
Globally unique identifier |
setGuidIsPermaLink(boolean) |
Whether the GUID is a URL (default: true) |
setComments(String) |
URL to comments page for this item |
setSource(String, String) |
Source feed name and URL |
Note: At least one of title or description must be set for a valid RSS item. The RSS 2.0 specification requires that every item has at least one of these two elements.
6. Categories
Categories can be applied to both channels and items. Each category has a text value and an optional domain attribute that identifies the categorization taxonomy.
Channel Categories
channel.addCategory("Technology");
channel.addCategory("Java", "http://example.com/categories");
Item Categories
RssItem item = new RssItem("Post Title", "https://example.com/post", "Summary");
item.addCategory("Programming")
.addCategory("Frameworks")
.addCategory("Java", "http://example.com/languages");
Using RssCategory Directly
The addCategory() convenience methods create RssCategory objects
internally. You can also construct them directly if needed:
RssCategory category = new RssCategory("Open Source", "http://example.com/topics");
XmlElement xml = category.toXmlElement();
// <category domain="http://example.com/topics">Open Source</category>
7. Media Enclosures
Enclosures attach media files (audio, video, images) to RSS items. This is the mechanism that powers podcast feeds. Each enclosure requires a URL, file size in bytes, and MIME type.
Podcast Episode
RssItem episode = new RssItem();
episode.setTitle("Episode 42: The Answer")
.setLink("https://podcast.example.com/ep42")
.setDescription("We discuss the meaning of everything.")
.setPubDate(new Date())
.setEnclosure(
"https://podcast.example.com/audio/ep42.mp3",
48500000,
"audio/mpeg"
);
channel.addItem(episode);
Using RssEnclosure Directly
RssEnclosure enclosure = new RssEnclosure(
"https://example.com/video/intro.mp4",
125000000,
"video/mp4"
);
item.setEnclosure(enclosure);
Common MIME Types
| Format | MIME Type |
|---|---|
| MP3 Audio | audio/mpeg |
| AAC Audio | audio/aac |
| MP4 Video | video/mp4 |
| PDF Document | application/pdf |
| JPEG Image | image/jpeg |
| PNG Image | image/png |
8. Channel Images
The channel image is a logo that feed readers may display alongside the channel title. It requires a URL (the image file), a title (alt text), and a link (the URL the image links to when clicked). Width and height are optional.
RssImage logo = new RssImage(
"https://example.com/images/logo.png",
"My Blog",
"https://example.com"
);
logo.setWidth(144).setHeight(100);
channel.setImage(logo);
Image Options
| Method | Default | Description |
|---|---|---|
setWidth(int) |
0 (omitted) | Image width in pixels (max 144) |
setHeight(int) |
0 (omitted) | Image height in pixels (max 400) |
setDescription(String) |
null |
Text description of the image |
Note: The RSS 2.0 specification recommends a default image size of 88x31 pixels, with a maximum of 144x400. Most modern feed readers will scale the image regardless.
9. RSS Extensions
The library supports two widely-used RSS extensions. Namespace declarations are automatically
added to the <rss> root element only when the corresponding features are used.
content:encoded
The content:encoded extension allows you to include the full HTML content of an
article within the feed, wrapped in a CDATA section. Feed readers that support this extension
will display the rich content instead of the plain-text description.
RssItem item = new RssItem(
"Styled Article",
"https://example.com/styled",
"A summary for feed readers that don't support content:encoded."
);
item.setContentEncoded(
"<h2>Full Article</h2>"
+ "<p>This is the <strong>complete</strong> HTML content.</p>"
+ "<img src='https://example.com/photo.jpg' />"
);
This produces:
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
...
<content:encoded><![CDATA[
<h2>Full Article</h2>
<p>This is the <strong>complete</strong> HTML content.</p>
<img src='https://example.com/photo.jpg' />
]]></content:encoded>
...
atom:link (Self Reference)
The atom:link extension adds a self-referencing URL to the channel, telling
feed readers where the feed itself lives. This is recommended for feed validation and
auto-discovery.
channel.setAtomSelfLink("https://example.com/feed");
This produces:
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
...
<atom:link href="https://example.com/feed" rel="self" type="application/rss+xml"/>
...
Best practice: Always set the atom self link. Most RSS validators will warn if it is missing, and feed readers use it to identify and deduplicate subscriptions.
10. Complete Example
This example demonstrates a full blog feed with channel metadata, an image, categories, multiple items, content encoding, and a podcast-style enclosure.
@Page("/feed")
public class BlogFeed extends RssFeed
{
@Override
protected RssChannel createChannel()
{
RssChannel channel = new RssChannel(
"Oorian Developer Blog",
"https://oorian.com/blog",
"Tutorials, tips, and news about the Oorian framework"
);
// Channel metadata
channel.setLanguage("en-us")
.setCopyright("Copyright 2026 Corvus Engineering")
.setManagingEditor("editor@oorian.com (Editor)")
.setLastBuildDate(new Date())
.setTtl(60)
.setAtomSelfLink("https://oorian.com/feed");
// Channel logo
channel.setImage(new RssImage(
"https://oorian.com/images/logo.png",
"Oorian",
"https://oorian.com"
));
// Channel categories
channel.addCategory("Technology");
channel.addCategory("Java");
// Items
RssItem post1 = new RssItem(
"Getting Started with Oorian",
"https://oorian.com/blog/getting-started",
"Learn how to build your first web app with Oorian."
);
post1.setAuthor("editor@oorian.com (Editor)")
.setPubDate(new Date())
.setGuid("https://oorian.com/blog/getting-started")
.addCategory("Tutorial")
.setContentEncoded(
"<p>Oorian lets you build web apps <strong>entirely in Java</strong>.</p>"
+ "<p>No JavaScript required.</p>"
);
RssItem post2 = new RssItem(
"Oorian Podcast: Episode 1",
"https://oorian.com/blog/podcast-ep1",
"Our first podcast episode about Java web development."
);
post2.setPubDate(new Date())
.setGuid("https://oorian.com/blog/podcast-ep1")
.addCategory("Podcast")
.setEnclosure(
"https://oorian.com/audio/episode1.mp3",
24500000,
"audio/mpeg"
);
channel.addItem(post1);
channel.addItem(post2);
return channel;
}
}
11. API Reference
RssFeed
Abstract base class for serving RSS feeds. Extends HttpFile.
| Method | Returns | Description |
|---|---|---|
createChannel() |
RssChannel |
Abstract — implement to build your feed's channel and items |
setCacheControl(CacheControl) |
void |
Override the default cache control (inherited from HttpFile). Default: CacheControl.preventCaching() |
setResponseHeader(String, String) |
void |
Set a custom HTTP response header (inherited from HttpFile) |
RssChannel
Represents the <channel> element. Constructor requires title, link, and description.
| Method | Returns | Description |
|---|---|---|
setLanguage(String) | RssChannel | Set channel language |
setCopyright(String) | RssChannel | Set copyright notice |
setManagingEditor(String) | RssChannel | Set editor email |
setWebMaster(String) | RssChannel | Set webmaster email |
setPubDate(Date) | RssChannel | Set publication date |
setLastBuildDate(Date) | RssChannel | Set last build date |
setGenerator(String) | RssChannel | Set generator string |
setDocs(String) | RssChannel | Set documentation URL |
setTtl(int) | RssChannel | Set cache TTL in minutes |
setImage(RssImage) | RssChannel | Set channel logo |
setAtomSelfLink(String) | RssChannel | Set feed self-reference URL |
addItem(RssItem) | RssChannel | Add an item to the feed |
addCategory(String) | RssChannel | Add a category |
addCategory(String, String) | RssChannel | Add a category with domain |
formatRfc822Date(Date) | String | Static — format a date as RFC 822 |
RssItem
Represents an <item> element. Can be created empty or with title, link, and description.
| Method | Returns | Description |
|---|---|---|
setTitle(String) | RssItem | Set item title |
setLink(String) | RssItem | Set item URL |
setDescription(String) | RssItem | Set item summary |
setAuthor(String) | RssItem | Set author email |
setComments(String) | RssItem | Set comments URL |
setEnclosure(RssEnclosure) | RssItem | Set media enclosure |
setEnclosure(String, long, String) | RssItem | Set enclosure by URL, size, MIME type |
setGuid(String) | RssItem | Set unique identifier |
setGuidIsPermaLink(boolean) | RssItem | Set whether GUID is a URL |
setPubDate(Date) | RssItem | Set publication date |
setSource(String, String) | RssItem | Set source feed name and URL |
setContentEncoded(String) | RssItem | Set full HTML content (CDATA) |
addCategory(String) | RssItem | Add a category |
addCategory(String, String) | RssItem | Add a category with domain |
RssImage
Represents the channel <image> element. Constructor requires url, title, and link.
| Method | Returns | Description |
|---|---|---|
setWidth(int) | RssImage | Set width in pixels (max 144) |
setHeight(int) | RssImage | Set height in pixels (max 400) |
setDescription(String) | RssImage | Set image description |
RssEnclosure
Represents an <enclosure> element. Constructor requires url, length, and MIME type.
| Constructor Parameter | Type | Description |
|---|---|---|
url | String | URL of the media file |
length | long | File size in bytes |
type | String | MIME type (e.g., "audio/mpeg") |
RssCategory
Represents a <category> element with optional domain.
| Constructor | Description |
|---|---|
RssCategory(String value) | Category with text value only |
RssCategory(String value, String domain) | Category with value and domain URI |
12. Troubleshooting
Feed shows as plain text in browser
Modern browsers no longer render RSS feeds natively. The XML will display as plain text or a raw XML tree. Use a feed reader (Feedly, Inoreader, etc.) or a browser extension to preview the formatted feed. You can also validate the XML by viewing the page source.
Dates display incorrectly
RSS 2.0 requires RFC 822 formatted dates. Always use java.util.Date objects
with the item and channel setters — the library handles formatting automatically via
RssChannel.formatRfc822Date(). Do not pass pre-formatted date strings.
Namespace not appearing in output
The xmlns:content and xmlns:atom namespace declarations are only
added to the <rss> element when the corresponding features are used.
If you don't see the content namespace, make sure at least one item has called
setContentEncoded(). If you don't see the atom namespace, make sure you've
called setAtomSelfLink() on the channel.
Feed validator reports errors
Run your feed through the W3C Feed Validation Service to check for issues. Common fixes:
- Set
setAtomSelfLink()to the URL where your feed is served - Ensure every item has at least a title or description
- Use the full email format for authors:
"user@example.com (Display Name)"
Special characters in content
Text set via setText() on XML elements is automatically XML-escaped by
Oorian's XmlElement. HTML content in setContentEncoded() is
wrapped in CDATA, so it does not need escaping. You do not need to manually escape
ampersands, angle brackets, or quotes in either case.