Twitter Logo Follow us on Twitter
Project Information About this project

Static Resources and Downloads

Registering Static Resources

Every RAP application can host it's own static resources, like documents, scripts, images, or CSS-files. These can then be used

It is not necessary to register images used by CSS theming.

There are multiple ways to register a resource, with the main difference beeing the time and place the registration happens.

  • The ApplicationConfiguration is a good place to register resources that you know will be required throughout your applications lifecycle. Example:
    application.addResource( "foo/icon.png", new ResourceLoader() {
      @Override
      public InputStream getResourceAsStream( String resourceName ) throws IOException {
        return this.getClass().getClassLoader().getResourceAsStream( "resources/icon.png" );
      }
    } );
  • For workbench applications, the org.eclipse.rap.ui.resources extension point and IResource interface provide the same service as the application configuration above. One notable difference is that the extension also makes it simple for other bundles other than the RAP application itself to register resources. Also, any registered JavaScript file will automatically be executed when the web client is loaded. The ClientFileLoader is not required in that case. Example for plugin.xml:
    <extension point="org.eclipse.rap.ui.resources">
      <resource class="my.project.resources.IconResource">
      </resource>
    </extension>
  • The most universal approach is using the ResourceManager directly, which allows registering and de-registering any resource at any time.
    ResourceManager resourceManager = RWT.getResourceManager();
    if( !resourceManager.isRegistered( "foo/icon.png" ) ) {
      InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream( "resources/icon.png" );
      try {
        resourceManager.register( resourceName, inputStream );
      } finally {
        inputStream.close();
      }
    }

Important: To use the resource on the client (e.g. in a browser widget or the JavaScriptLoader), is it necessary to know it's public URL from the clients point of view. (The favicon in the application configuration/branding is an exception, it can use the path given during registration). This information is in all cases provided by the ResourceManager:

String src = RWT.getResourceManager().getLocation( "foo/icon.png" );

Service Handler and Downloads

If you want to provide downloads in your RAP application, you can use a service handler instead of static resources. Below is an example of a very basic downloads service handler.

public class DownloadServiceHandler implements ServiceHandler {

  public void service( HttpServletRequest request, HttpServletResponse response )
    throws IOException, ServletException
  {
    // Which file to download?
    String fileName = request.getParameter( "filename" );
    // Get the file content
    byte[] download = MyDataStore.getByteArrayData( fileName );
    // Send the file in the response
    response.setContentType( "application/octet-stream" );
    response.setContentLength( download.length );
    String contentDisposition = "attachment; filename=\"" + fileName + "\"";
    response.setHeader( "Content-Disposition", contentDisposition );
    response.getOutputStream().write( download );
  }
}

The request has a parameter "filename" which indicates which content (either static or dynamically generated) should be sent to the client. The MyDataStore-line is a placeholder for whatever code is required to provide the content. In our example the content is retrieved as byte[], but InputStreams and Readers can be easily accommodated as well.

The service handler has to be registered, like static resources, once per application. The best place to do this is (depending on your application setup) either the Application Configuration or org.eclipse.rap.ui.serviceHandler extension. If need be it can also be done at runtime:

ServiceManager manager = RWT.getServiceManager();
ServiceHandler handler = new DownloadServiceHandler();
manager.registerServiceHandler( "downloadServiceHandler", handler );

The URL for the download link can be generated as follows:

private String createDownloadUrl( String filename ) {
  StringBuilder url = new StringBuilder();
  url.append( RWT.getServiceManager().getServiceHandlerUrl( "downloadServiceHandler" ) );
  url.append( '&' ).append( "filename" ).append( '=' ).append( filename );
  return url.toString();
}

The link can either be embedded using markup, or opened programmatically with the URLLauncher. The application can not control whether certain file types are opened in a browser popup/tab/window, or in a "save-as" dialog. This is completely up to the browser. However, a markup hyperlink usually has a native context menu with a "save-as" entry.