Generating non-HTML responses

A normal concern in Web Development is to generate several documents besides normal HTML Page Documents.
A few examples can be the following list:

  • Images (charts, labeled images, maps, etc.)
  • PDF, Word, Excel, etc: For reports, or data export
  • XML: For data export

When these are static files on the web application resource bundle, one simply has to insert the correct URL in the HTML/JSP page. But when they must be dynamically generated at run time, given some context information, we normally have to create a set of common features to achieve this. Such as:

  • Content specific generation (using a specific API for PDF, PNG, JPEG, DOC, or any other content needed)
  • Stream output export of the generated document
  • Servlet to convey the generated output stream in the correct HTTP response type

DiF, with the following set of features simplifies and automates much of these common implementation needs.

@OnDocument methods

First of all, the task of generating the document.
DiF provides a special annotation named @OnDocument that declares any given stage method as a document generation event handler.

Let's see a simple sample usage...

    /**
     * @return the excel document
     */
    @OnDocument("servicesExcel")
    public IDocumentResponse getServicesExcel() {
        DocumentResponseEXCELImpl resp = new DocumentResponseEXCELImpl("servicesDoc");
        List<ServiceRecord> services = new ArrayList<ServiceRecord>();

        for (IProvider provider: providers)
            for (IApplication application: provider.getApplications().values())
                for (IService service: application.getServices().values())
                    services.add(new ServiceRecord(service));

        resp.getDocument().addData(services);

        return resp;
    }

Above you can see the getServicesExcel method annotated with the @OnDocument annotation.
Notice the "servicesExcel" ID assigned to the handler on the annotation. This will be the internal name that DiF will use to reference this event handler.

You can also notice that it has a specific return type, the IDocumentResponse.
This interface specifies what any document type should provide, in order to DiF's automation take care of it's generation and publishing. More on this on the following section.

When we declare such a method, it will instantly become available in the documents servlet. To access it one simply has to use the proper URL. Let's assume that this method belongs to a stage with the ID "somestage".

The URL for this stage would be:
http://server/appRoot/page?stage=somestage

To access the document, we would call:
http://server/appRoot/doc?stage=somestage&_event=servicesExcel

Notice the differences!
This provided DiF servlet automatically does all the content generation for our document.
All it needs to know is defined by the IDocumentResponse interface, and thus is available.

Further more, we need not generate these non user friendly URLs by hand. DiF has a tag just for this. More on this bellow.

IDocumentResponse interface

As we stated before, the IDocumentResponse defines a DiF standard document response object. These can be fairly complicated. One normally needs to use third-party APIs to be able to generate the specific formats, and, for convinience DiF provides a few of them for our usage.

DiF bundled document response implementations:

These are default implementations that trivialize the generation of these document formats.

In the above example we can see the Excel implementation in action.

document UI component

The documentGeneration component generates the HTML link for any document. This component will correctly show the document type, and other useful features.

On it's simplest form, it will automate the correct URL generation, but it can be asked to do much more. See the documentation for more usage information.

Sample usage, a full example

For a complete example we will pick up the previous code sample, explain and complement it.

The stage

The stage event handler method.

    /**
     * @return the excel document
     */
    @OnDocument("servicesExcel")
    public IDocumentResponse getServicesExcel() {
        DocumentResponseEXCELImpl resp = new DocumentResponseEXCELImpl("servicesDoc");
        List<ServiceRecord> services = new ArrayList<ServiceRecord>();

        for (IProvider provider: providers)
            for (IApplication application: provider.getApplications().values())
                for (IService service: application.getServices().values())
                    services.add(new ServiceRecord(service));

        resp.getDocument().addData(services);

        return resp;
    }

First we declare an Excel document response object. Notice the document name in the constructor. This will be the generated Excel file to download.
We then iterate on all DiF services and add them to a list attribute.
In the end, we simply use the addData method of the document response Excel API to add the data to the Excel document. It will infer all correct attributes from the Bean class.

To finish we return the created object response and we're done.

The view template

On the presentation layer it is even simpler.
All we need to do is add the following component to our page.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/difcore" prefix="dif"%>
<dif:document>
    <dif:documentGenerator eventID="servicesExcel" message="Download service list in Excel"/>
</dif:document>

And it is as simple as that!

Back to User Guide index