A project of The Apache Software Foundation
Navigation

How to generate dynamic content like PDFs or JSON

Learn how to create custom resources that generate files on the fly, such as RSS feeds, CSV exports, or PDF documents

In Wicket the best way to add dynamic functionalities to our application (such as csv export, a pdf generated on the fly, etc…) is implementing a custom resource. In this paragraph as example of custom resource we will build a basic RSS feeds generator which can be used to publish feeds on our site (project CustomResourceMounting). Instead of generating a RSS feed by hand we will use Rome framework and its utility classes.

As hinted above in paragraph 16.1, class AbstractResource can be used as base class to implement new resources. This class defines abstract method newResourceResponse which is invoked when the resource is requested. The following is the code of our RSS feeds generator:

public class RSSProducerResource extends AbstractResource {

  @Override
  protected ResourceResponse newResourceResponse(Attributes attributes) {
    ResourceResponse resourceResponse = new ResourceResponse();
    resourceResponse.setContentType("text/xml");
    resourceResponse.setTextEncoding("utf-8");
    
    resourceResponse.setWriteCallback(new WriteCallback()
    {
      @Override
      public void writeData(Attributes attributes) throws IOException
      {
        OutputStream outputStream = attributes.getResponse().getOutputStream();
        Writer writer = new OutputStreamWriter(outputStream);
        SyndFeedOutput output = new SyndFeedOutput();
            try {
          output.output(getFeed(), writer);
        } catch (FeedException e) {
          throw new WicketRuntimeException("Problems writing feed to response...");
        }
      }      
    });
    
    return resourceResponse;
  }
  // method getFeed()...
}

Method newResourceResponse returns an instance of ResourceResponse representing the response generated by the custom resource. Since RSS feeds are based on XML, in the code above we have set the type of the response to text/xml and the text encoding to utf-8.

To specify the content that will be returned by our resource we must also provide an implementation of inner class WriteCallback which is responsible for writing content data to response’s output stream. In our project we used class SyndFeedOutput from Rome framework to write our feed to response. Method getFeed() is just an utility method that generates a sample RSS feed (which is an instance of interface com.rometools.rome.feed.synd.SyndFeed).

Now that we have our custom resource in place, we can use it in the home page of the project. The easiest way to make a resource available to users is to expose it with link component ResourceLink:

add(new ResourceLink("rssLink", new RSSProducerResource()));

In the next paragraphs we will see how to register a resource at application-level and how to mount it to an arbitrary URL.