Web applications work over the web and have various resources, such
as images or downloadable files, that the web browser has to get from
the server. These resources are typically used in
Embedded
(images) or
Link
(downloadable files) user interface
components. Various components, such as
TabSheet
, can also include icons, which are
also handled as resources.
A web server can handle many of such requests for static resources without
having to ask them from the application, or the
Application
object can provide them. For dynamic
resources, the user application must be able to create them
dynamically. Vaadin provides resource request interfaces for applications so
that they can return various kinds of resources, such as files or dynamically
created resources. These include the StreamResource
class and URI and parameter handlers described in Section 12.5.1, “URI Handlers” and Section 12.5.2, “Parameter Handlers”, respectively.
Vaadin provides also low-level facilities for retrieving the URI and other parameters of a HTTP request. We will first look into how applications can provide various kinds of resources and then 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. Please see Section 12.1, “Special Characteristics of AJAX Applications” for a detailed explanation.
Vaadin has two interfaces for resources: a generic
Resource
interface and a more specific
ApplicationResource
interface for resources
provided by the application.
ApplicationResource
resources are managed
by the Application
class. When you create
such a resource, you give the application object to the
constructor. The constructor registers the resource in the
application using the addResource
method.
Application
manages requests for the
resources and allows accessing resources using a URI. The URI
consists of the base name of the application and a relative name
of the resource. The relative name is
"APP/"+resourceid+"/"+filename
, for example
"APP/1/myimage.png"
. The
resourceid
is a generated numeric identifier
to make resources unique, and filename
is the
file name of the resource given in the constructor of its
class. However, the application using a resource does not usually
need to consider its URI. It only needs to give the resource to
an appropriate Embedded
or
Link
or some other user interface
component, which manages the rendering of the URI.
File resources are files stored anywhere in the file system. The use of file resources generally falls into two main categories: downloadable files and embedded images.
A file object that can be accessed as a file resource is defined with the
standard java.io.File
class. You can create the
file either with an absolute or relative path, but the base path of the
relative path depends on the installation of the web server. For example,
in Apache Tomcat, the default current directory is the installation path of
Tomcat.
The ClassResource
allows resources to be loaded
from the deployed package of the application using Java Class Loader. The one-line example below loads an image resource from
the application package and displays it in an
Embedded
component.
mainwindow.addComponent(new Embedded ("", new ClassResource("smiley.jpg", mainwindow.getApplication())));
Theme resources of ThemeResource
class are files,
typically images, included in a theme. A theme is located with path
VAADIN/themes/themename
in a web application. Name of
a theme resource is given as the parameter for the constructor, with a
path relative to the theme folder.
// A theme resource in the current theme ("book-examples") // Located in: VAADIN/themes/book-examples/img/themeimage.png ThemeResource resource = new ThemeResource("img/themeimage.png"); // Use the resource Embedded image = new Embedded("My Theme Image", resource);
The result is shown in Figure 4.5, “Theme Resources”, illustrating also the folder structure for the theme resource file in an Eclipse project.
To use theme resources, you must set the theme for the application. See Chapter 8, Themes for more information regarding themes.
Stream resources are application resources that allow creating
dynamic resource content. Charts are typical examples of dynamic
images. To define a stream resource, you need to implement the
StreamResource.StreamSource
interface and
its getStream
method. The method needs
to return an InputStream
from which the
stream can be read.
The following example demonstrates the creation of a simple image in PNG image format.
import java.awt.image.*; public class MyImageSource implements StreamResource.StreamSource { ByteArrayOutputStream imagebuffer = null; int reloads = 0; /* We need to implement this method that returns * the resource as a stream. */ public InputStream getStream () { /* Create an image and draw something 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); drawable.setColor(Color.black); drawable.drawString("Reloads="+reloads, 75, 100); reloads++; try { /* Write the image to a buffer. */ imagebuffer = new ByteArrayOutputStream(); ImageIO.write(image, "png", imagebuffer); /* Return a stream from the buffer. */ return new ByteArrayInputStream( imagebuffer.toByteArray()); } catch (IOException e) { return null; } } }
The content of the generated image is dynamic, as it updates the
reloads counter with every call. The
ImageIO
.write()
method writes the image to an output stream, while we had to
return an input stream, so we stored the image contents to a
temporary buffer.
You can use resources in various ways. Some user interface components, such as
Link
and Embedded
,
take their parameters as a resource.
Below we display the image with the
Embedded
component. The
StreamResource
constructor gets a
reference to the application and registers itself in the
application's resources. Assume that main
is a
reference to the main window and this
is the
application object.
// Create an instance of our stream source. StreamResource.StreamSource imagesource = new MyImageSource (); // Create a resource that uses the stream source and give it a name. // The constructor will automatically register the resource in // the application. StreamResource imageresource = new StreamResource(imagesource, "myimage.png", this); // Create an embedded component that gets its contents // from the resource. main.addComponent(new Embedded("Image title", imageresource));
The image will look as follows:
We named the resource as myimage.png
. The
application adds a resource key to the file name of the resource
to make it unique. The full URI will be like
http://localhost:8080/testbench/APP/1/myimage.png
. The
end APP/1/myimage.png
is the
relative part of the URI. You can get the
relative part of a resource's URI from the application with
Application.getRelativeLocation()
.
Another solution for creating dynamic content is an URI handler, possibly together with a parameter handler. See Section 12.5.1, “URI Handlers” and Section 12.5.2, “Parameter Handlers”.