About Eyal Golan

Eyal is a professional software engineer and an architect. He is a developer and leader of highly sophisticated systems in different areas, such as networking, security, commerce and more

RSS Reader Using: ROME, Spring MVC, Embedded Jetty

In this post I will show some guidelines to create a Spring web application, running it using Jetty and using an external library called ROME for RSS reading.

General

I have recently created a sample web application that acts as an RSS reader. I wanted to examine ROME for RSS reading. I also wanted to create the application using Spring container and MVC for the simplest view. For rapid development, I used Jetty as the server, using a simple java class for it.
All the code can be found at GitHub, eyalgo/rss-reader.
 

Content

  1. Maven Dependencies
  2. Jetty Server
  3. Spring Dependency
  4. Spring MVC
  5. ROME

Maven Dependencies

At first, I could not get the correct Jetty version to use. There is one with group-id mortby, and another by eclipse. After some careful examination and trial and error, I took the eclipse’s library. Spring is just standard. I found ROME with newest version under GutHub. It’s still a SNAPSHOT.

Here’s the list of the dependencies:

  • Spring
  • jetty
  • rome and rome-fetcher
  • logback and slf4j
  • For Testing
    • Junit
    • mockito
    • hamcrest
    • spring-test

Jetty Server

A few years ago I’ve been working using Wicket framework and got to know Jetty, and its easy usage for creating a server. I decided to go in that direction and to skip the standard web server running with WAR deployment.

There are several ways to create the Jetty server. I decided to create the server, using a web application context.

First, create the context:

private WebAppContext createContext() {
  WebAppContext webAppContext = new WebAppContext();
  webAppContext.setContextPath("/");
  webAppContext.setWar(WEB_APP_ROOT);
  return webAppContext;
}

Then, create the server and add the context as handler:

Server server = new Server(port);
  server.setHandler(webAppContext);

Finally, start the server:

try {
    server.start();
  } catch (Exception e) {
    LOGGER.error("Failed to start server", e);
    throw new RuntimeException();
  }

Everything is under https://github.com/eyalgo/rss-reader/tree/master/src/test/java/com/eyalgo/rssreader/server.

Spring Project Structure

RSS Reader Project Structure

RSS Reader Project Structure

Spring Dependency

In web.xml I am declaring application-context.xml and web-context.xml . In web-context.xml , I am telling Spring were to scan for components: <context:component-scan base-package="com.eyalgo.rssreader"/>.
In application-context.xml I am adding a bean, which is an external class and therefore I can’t scan it (use annotations):
<bean id="fetcher" class="org.rometools.fetcher.impl.HttpURLFeedFetcher"/>.

Besides scanning, I am adding the correct annotation in the correct classes.
@Repository
@Service
@Controller
@Autowired

Spring MVC

In order to have some basic view of the RSS feeds (and atoms), I used a simple MVC and JSP pages. To create a controller, I needed to add @Controller for the class. I added @RequestMapping("/rss") so all requests should be prefixed with rss. Each method has a @RequestMapping declaration. I decided that everything is GET.

Adding a Parameter to the Request

Just add @RequestParam("feedUrl") before the parameter of the method.

Redirecting a Request

After adding an RSS location, I wanted to redirect the answer to show all current RSS items. So the method for adding an RSS feed needed to return a String. The returned value is: “redirect:all”.

@RequestMapping(value = "feed", method = RequestMethod.GET)
  public String addFeed(@RequestParam("feedUrl") String feedUrl) {
    feedReciever.addFeed(feedUrl);
    return "redirect:all";
  }

Return a ModelAndView Class

In Spring MVC, when a method returns a String, the framework looks for a JSP page with that name. If there is none, then we’ll get an error. (If you want to return just the String, you can add @ResponseBody to the method.)

In order to use ModelAndView, you need to create one with a name: ModelAndView modelAndView = new ModelAndView("rssItems");
The name will tell Spring MVC which JSP to refer to. In this example, it will look for rssItems.jsp.

Then you can add to the ModelAndView “objects”:

List<FeedItem> items = itemsRetriever.get();
  ModelAndView modelAndView = new ModelAndView("rssItems");
  modelAndView.addObject("items", items);

In the JSP page, you need to refer the names of the objects you added. And then, you can access their properties. So in this example, we’ll have the following in rssItems.jsp:

<c:forEach items="${items}" var="item">
    <div>
      <a href="${item.link}" target="_blank">${item.title}</a><br>
        ${item.publishedDate}
    </div>
  </c:forEach>

Note

Spring “knows” to add jsp as a suffix to the ModelAndView name because I declared it in web-context.xml. In the bean of class: org.springframework.web.servlet.view.InternalResourceViewResolver. By setting the prefix this bean also tells Spring were to look for the jsp pages. Please look:

Error Handling

There are several ways to handle errors in Spring MVC. I chose a generic way, in which for any error, a general error page will be shown. First, add @ControllerAdvice to the class you want to handle errors. Second, create a method per type of exception you want to catch. You need to annotate the method with @ExceptionHandler. The parameter tells which exception this method will handle. You can have a method for IllegalArgumentException and another for different exception and so on. The return value can be anything and it will act as normal controller. That means, having a jsp (for example) with the name of the object the method returns. In this example, the method catches all exception and activates error.jsp, adding the message to the page.

@ExceptionHandler(Exception.class)
  public ModelAndView handleAllException(Exception e) {
    ModelAndView model = new ModelAndView("error");
    model.addObject("message", e.getMessage());
    return model;
  }

ROME

ROME is an easy to use library for handling RSS feeds : https://github.com/rometools/rome.
rome-fetcher is an additional library that helps getting (fetching) RSS feeds from external sources, such as HTTP, or URL : https://github.com/rometools/rome-fetcher

As of now, the latest build is 2.0.0-SNAPSHOT .

An example on how to read an input RSS XML file can be found at: https://github.com/eyalgo/rss-reader/blob/master/src/test/java/com/eyalgo/rssreader/runners/MetadataFeedRunner.java

To make life easier, I used rome-fetcher. It gives you the ability to give a URL (RSS feed) and have all the SyndFeed out of it. If you want, you can add caching, so it won’t download cached items (items that were already downloaded). All you need is to create the fetcher with FeedFetcherCache parameter in the constructor.

Usage:

@Override
  public List<FeedItem> extractItems(String feedUrl) {
    try {
      List<FeedItem> result = Lists.newLinkedList();
      URL url = new URL(feedUrl);
      SyndFeed feed = fetcher.retrieveFeed(url);
      List<SyndEntry> entries = feed.getEntries();
      for (SyndEntry entry : entries) {
        result.add(new FeedItem(entry.getTitle(), entry.getLink(), entry.getPublishedDate()));
      }
      return result;
    } catch (IllegalArgumentException | IOException | FeedException | FetcherException e) {
      throw new RuntimeException("Error getting feed from " + feedUrl, e);
    }
}

Note

If you get a warning message (looks as System.out) that tells that fetcher.properties is missing, just add an empty file under resources (or in the root of the classpath).

Summary

This post covered several topics. You can also have a look at the way a lot of the code is tested. Check Matchers and mocks. If you have any remarks, please drop a note.

Related Whitepaper:

Introduction to Web Applications Development

Kick start your web apps development with this introductory ebook!

This 376 page eBook 'Introduction to Web Applications Development', starts with an introduction to the internet, including a brief history of the TCT/IP protocol and World Wide Web. It defines the basic concepts for web servers and studies the case of Apache, the most used webserver, while other free software webservers are not forgotten. It continues with webpage design focusing on HTML and JavaScript. XML Schemas, their validation and transformation are covered as well as dynamic webpages built with CGI, PHP or JSP and database access.

Get it Now!  

Leave a Reply


eight × 4 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books