In addition to high-level resource classes described in Section 4.5, “Referencing Resources”, Vaadin provides low-level facilities for retrieving the URI and other parameters of HTTP requests. In the following, we will look into low-level interfaces for handling URIs and parameters to provide resources and functionalities.

Notice that using URI or parameter handlers to create "pages" is not meaningful in Vaadin or in AJAX applications generally. See Section 12.1, “Special Characteristics of AJAX Applications” for reasons.

The URI parameter for the application is useful mainly for two purposes: for providing some special functionality according to the URI or for providing dynamic content. Dynamic content can also be provided with StreamResource.

You can retrieve the URI for the HTTP request made for your application by implementing the com.vaadin.terminal.URIHandler interface. The handler class needs to be registered in the main window object of your application with the addURIHandler() method. You then get the URI by implementing the handleURI() method. The method gets two parameters: a context and a URI relative to the context. The context is the base URI for your application.

public void init() {
    final Window main = new Window("Hello window");
    setMainWindow(main);

    URIHandler uriHandler = new URIHandler() {
        public DownloadStream handleURI(URL context,
                                        String relativeUri) {
            // Do something here
            System.out.println("handleURI=" + relativeUri);

            // Should be null unless providing dynamic data.
            return null;
        }
    };
    main.addURIHandler(uriHandler);

}

If you have multiple URI handlers attached to a window, they are executed after one another. The URI handlers should return null, unless you wish to provide dynamic content with the call. Other URI handlers attached to the window will not be executed after some handler returns non-null data. The combined parameter and URI handler example below shows how to create dynamic content with a URI handler.

Notice that if you do provide dynamic content with a URI handler, the dynamic content is returned in the HTTP response. If the handler makes any changes to the UI state of the application, these changes are not rendered in the browser, as they are usually returned in the HTTP response made by the Application object and now the custom URI handler overrides the default behaviour. If your client-side code makes a server call that does update the UI state, the client-side must initiate an update from the server. For example, if you have an integration situation where you make a JavaScript call to the server, handle the request with a URI handler, and the server state changes as a side-effect, you can use the vaadin.forceSync() method to force the update.

You can retrieve the parameters passed to your application by implementing the com.vaadin.terminal.ParameterHandler interface. The handler class needs to be registered in the main window object of your application with the addParameterHandler() method. You then get the parameters in the handleParameters() method. The parameters are passes as a map from string key to a vector of string values.

class MyParameterHandler implements ParameterHandler {
    public void handleParameters(Map parameters) {
        // Print out the parameters to standard output
        for (Iterator it = parameters.keySet().iterator();
             it.hasNext();) {
            String key   = (String) it.next();
            String value = ((String[]) parameters.get(key))[0];
            System.out.println("Key: "+key+", value: "+value);
        }
    }
}

The parameter handler is not called if there are no parameters. Parameter handler is called before the URI handler, so if you handle both, you might typically want to just store the URI parameters in the parameter handler and do actual processing in URI handler. This allows you, for example, to create dynamic resources based on the URI parameters.

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.Map;
import javax.imageio.ImageIO;
import com.vaadin.terminal.*;

/**
 * Demonstrates handling URI parameters and the URI itself to
 * create a dynamic resource.
 */
public class MyDynamicResource implements URIHandler,
                                          ParameterHandler {
    String textToDisplay = "- no text given -";

    /**
     * Handle the URL parameters and store them for the URI
     * handler to use.
     */
    public void handleParameters(Map parameters) {
        // Get and store the passed HTTP parameter.
        if (parameters.containsKey("text"))
            textToDisplay =
                ((String[])parameters.get("text"))[0];
    }

    /**
     * Provides the dynamic resource if the URI matches the
     * resource URI. The matching URI is "/myresource" under
     * the application URI context.
     * 
     * Returns null if the URI does not match. Otherwise
     * returns a download stream that contains the response
     * from the server.
     */
    public DownloadStream handleURI(URL context,
                                    String relativeUri) {
        // Catch the given URI that identifies the resource,
        // otherwise let other URI handlers or the Application
        // to handle the response.
        if (!relativeUri.startsWith("myresource"))
            return null;
        
        // Create an image and draw some background on it.
        BufferedImage image = new BufferedImage (200, 200,
                                    BufferedImage.TYPE_INT_RGB);
        Graphics drawable = image.getGraphics();
        drawable.setColor(Color.lightGray);
        drawable.fillRect(0,0,200,200);
        drawable.setColor(Color.yellow);
        drawable.fillOval(25,25,150,150);
        drawable.setColor(Color.blue);
        drawable.drawRect(0,0,199,199);
        
        // Use the parameter to create dynamic content.
        drawable.setColor(Color.black);
        drawable.drawString("Text: "+textToDisplay, 75, 100);

        try {
            // Write the image to a buffer.
            ByteArrayOutputStream imagebuffer =
                    new ByteArrayOutputStream();
            ImageIO.write(image, "png", imagebuffer);

            // Return a stream from the buffer.
            ByteArrayInputStream istream =
                    new ByteArrayInputStream(
                            imagebuffer.toByteArray());
            return new DownloadStream (istream,null,null);
        } catch (IOException e) {
            return null;
        }
    }
}

When you use the dynamic resource class in your application, you obviously need to provide the same instance of the class as both types of handler:

MyDynamicResource myresource = new MyDynamicResource();
mainWindow.addParameterHandler(myresource);
mainWindow.addURIHandler(myresource);