Implementing RSS Feeds with new features of Spring 3

In this post I explain how we implemented the way we created the RSS feeds in a project and the challenges that we had during the set-up.

My colleague Jettro Coenradie explained in a previous post how you can create a feed using Rome and Spring 3, but didn’t elaborated on the Spring 3 part. I will explain how we used Spring 3 to create the feeds.

Context

In this project we need to support a large number of different feeds. As an example I will use the news feed that we need to create for different subjects. The subjects are created in a CMS and therefore people can add subjects whenever they want. This means that we want to support dynamically created feeds.

Annotations

The first thing you might notice when you look at the code above are the two annotations (@SessionManagedDaos and @RequestMapping) on the method. The @SessionManagedDaos is an annotation that is created by us. This annotation manages the session that we use from the CMS connection pool.

The second annotation is the @RequestMapping. This annotation has the value “/subjects/{subjectName}/news.rss” which means that every path that matches this pattern will be mapped to this method. In this pattern uses a new feature of Spring 3, namely the variable in the path. The @PathVariable annotation in front of the parameter subjectName indicates that the variable in the path needs to be bound to the method parameter.

This helps us to support any request with a given subject name and therefore we do not need to change the code if a new subject is created.

Wrong request

With the freedom of the path pattern also comes the problem that a person can try any subject name that he wants. In order to prevent that we execute a query for a subject that does not exist, we execute a query that finds the subject. If the subject is not found, we throw a NoSuchRequestHandlingMethodException. This exception is handled by the DefaultHandlerExceptionResolver. This resolver handles certain standard Spring MVC exceptions by setting a specific response status code. In our case the status code will be a 404.

Items

The implementation of the controller is not special. We execute a query that finds some news and with the help of a mapper, we map the retrieved beans to RSS items. These items, as well as the subject title, are added to the model.

View

Now that our model is filled, we can create the view. Spring 3 provides us with the AbstractRssFeedView. This view has a few entry points to create the feed.

We created a BaseRssFeedView which extends the AbstractRssFeedView. The BaseRssFeedView overrides three methods that build the feed.

I don’t want to discuss the implementation of the methods, as I think that they are pretty self-explanatory. But I do want to discuss the one abstract method that needs to be implemented by the subclasses. This method allows the subclass to specify the specific metadata for the feed. The code below shows the view that would belong to our SubjectRssController.

The class is annotated with @Component(“subjectRssFeed”). The name of the view is subjectRssFeed and needs to match with the view name you return in the controller.

Properties

In this case we assume that every subject has the same message for the specific metadata. So the only thing that differs is the subject name. For example, the description of a feed of the subject cars could be: This feed contains the news items of the subject cars.

So this means that we need to parameterize the messages. In order to do that we have created a class that resolves the message for us from the correct property file. This way we can still use the templates in the property files.

subject.news.rss.feed.description=This feed contains the news items of the subject {0}

Spring 3 also lets you annotate a field or method/constructor parameter that indicates a default value expression for the affected argument. This means you could inject a property like this: