ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Sliding into WebDAV

by Andrew Anderson
12/23/2003

Apache's Jakarta project offers all kinds of great open source resources to Java developers. One of Jakarta's less well-known but extremely useful subprojects is Slide. Slide is composed of a number of different modules, all tied together using the WebDAV protocol. These modules include implementations of a number of useful features such as a WebDAV client library, a WebDAV server library, and a WebDAV-based content management system. Among other uses, these modules give developers the ability to add WebDAV client functionality to their Java applications.

This article gives an introduction to using the Slide WebDAV client functionality in Java applications. The article will start with an overview of the WebDAV protocol, followed by an overview of the Slide project. Finally, we will get our hands dirty with some examples of using the Slide WebDAV client libraries in your applications.

WebDAV

WebDAV stands for "Web-based Distributed Authoring and Versioning." WebDAV is a set of extensions to the HTTP protocol that allows users to collaboratively edit and manage files on remote servers. While the protocol extensions themselves are simple and easy to use, the power that they add to an HTTP server is incredible. In effect, WebDAV makes an HTTP server an advanced remote file system. While protocols such as FTP have provided similar capabilities for years, WebDAV's features go beyond those that are in the standard FTP protocol, and therefore allow developers to use WebDAV to create more powerful applications.

While the implementations of various WebDAV servers offer different levels of protocol support, the following features are generally available and are what set WebDAV apart from protocols such as FTP:

  • HTTP-based: Allows all of the advantages of HTTP (file permissions, faster transfers, HTTPS support, etc.).
  • put: The ability to upload resources to a server.
  • lock: The ability to set/unset connection-independent, long-duration exclusive and shared locks on resources.
  • Properties: The ability to store arbitrary metadata for resources.
  • Namespace manipulations: The ability to move files, copy files, create directories and list directories.

These features allow the development of all sorts of interesting applications, including distributed web-page authoring/editing applications, version control applications, mail servers, and distributed calendaring applications, just to name a few. When developers combine WebDAV with the "Write Once, Run Anywhere" capabilities of Java, writing multiplatform distributed client applications becomes very simple.

WebDAV Tools and Resources

Like HTTP, WebDAV requires both client and server components. In addition to the Slide project, which provides binaries and libraries for both clients and servers, there are plenty of WebDAV components available:

  • The mod_dav Apache module adds WebDAV capabilities to Apache (included in Apache 2).
  • Microsoft's Internet Information Server includes WebDAV server support.
  • Mac OS X allows mounting of WebDAV servers as network disks.
  • The iDisk offered by Apple's .Mac service uses WebDAV servers, and the iCal program uses WebDAV to publish calendars.

More information on WebDAV (including information on mod_dav) is available from The WebDAV Resources Page.

The Slide Project

As we said earlier, the Slide project's home page describes Slide as "a project composed of multiple modules tied together using WebDAV." These "multiple modules" include:

  • A content management system with a Java API.
  • A servlet implementing the WebDAV protocol on top of the content management system.
  • A Java WebDAV and HTTP client library.
  • A WebDAV command-line client.
  • WebDAV-enabled Swing components (this module is on the features list but not yet implemented).

Like all Jakarta projects, Slide is available in both binary and source distributions. The binary distribution includes all of the classes needed to implement the WebDAV client examples in this article, and is available at Jakarta's binary download page. The binary distribution also includes the binaries for the server, the documentation for Slide, and the JavaDoc for the WebDAV client and server classes. While the binary distribution includes everything that you need for the examples in this article, the source distribution includes the Java source for the Slide's WebDAV command-line client. This file offers insight into coding WebDAV clients with Slide and may be worth checking out. The source distribution is available at Jakarta's source download page.

Once you have the binary distribution downloaded and unzipped, check out client/lib. This directory contains all .jar files needed for the examples in this article, including the Slide WebDAV client libraries and the .jars for several additional libraries that the WebDAV client uses. (The additional libraries are all either distributed by Apache via their Apache license, or are distributed by Sun as part of the Java distribution.) The JavaDoc for the WebDAV client libraries is available in doc/clientjavadoc.

Using Slide

Now down to business: using the Slide WebDAV client libraries to connect to WebDAV servers. The Slide client library encapsulates almost all of the functionality we need to access a WebDAV server in the WebdavResource class. Accessing a WebDAV server involves three basic steps:

  • Open a connection to a WebDAV server.
  • Issue protocol requests and receive responses from the server.
  • Close the connection.

Opening the connection to a WebDAV server is handled via the WebdavResource's constructor. There are several ways to handle this; the most straightforward is to give the constructor an org.apache.util.HttpURL object that contains the URL for the server and user information.

Once the connection is established, we can issue protocol requests across the connection. These protocol request's are handled by a number of methods in WebdavResource, specifically:

  • aclfindMethod: Used to find Access Control Lists; not implemented in many WebDAV servers.
  • aclMethod: Used to set Access Control Lists; not implemented in many WebDAV servers.
  • copyMethod: Copies a resource from one location to another on the server.
  • deleteMethod: Deletes a resource from the server.
  • getMethod: Gets a resource from the server (the same as the HTTP GET command).
  • headMethod: Gets the header of a resource from the server (the same as the HTTP HEAD command).
  • list: Lists the resources in the current directory of the server.
  • lockMethod: Locks a resource on the server.
  • mkcolMethod: Makes a collection (i.e., a folder or directory) on the server.
  • moveMethod: Moves a resource from one location to another on the server.
  • optionsMethod: Retrieves the options that this server supports (the getDavCapabilities() and getAllowedMethods() methods also handle this functionality).
  • postMethod: Gets a resource from the server via an HTTP post (the same as the HTTP POST command).
  • propFindMethod: Retrieves a resource's properties.
  • propPatchMethod: Sets and edits a resource's properties.
  • putMethod: Puts a resource onto the server (similar to the FTP PUT command).
  • setPath: Sets the current path of the remote server.
  • unlockMethod: Unlocks a resource on the server.

Note: Some of Slide's documentation is weak. While this article will cover some of these methods, we will not go over all of them. Some of those we do not cover are especially poorly documented; the best source of information on these methods is the WebDAV protocol documents and plain old-fashioned experimentation.

WebdavResource has a number of other methods that perform a variety tasks; for full details, check out the online version of the WebDAV Client JavaDoc for more details.

Once you are done issuing your protocol requests, then you need to close the WebDAV connection. This is handled by WebdavResource's close() method.

A Simple Example

The simplest Slide WebDAV client program that you can write would do the following:

  • Open a connection.
  • Get a file.
  • Close the connection.

Really, this example is almost too simple, since this can be handled using classes from the java.net package. What this example gives us, though, is an overview of using the WebdavResource class and a structure for later examples.

Here is the code:

// Slide Simple WebDAV client example
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;

import org.apache.commons.httpclient.HttpException;
import org.apache.util.HttpURL;
import org.apache.webdav.lib.WebdavResource;

public class SlideTest {

    public static void main (String args[]) 
    {
        try
        {
            HttpURL hrl =
                new HttpURL("http://webdav-server");
            hrl.setUserInfo("user","pass");
            WebdavResource wdr =
                new WebdavResource(hrl);
            File fn = new File("remote-file");
            wdr.getMethod(fn);
            wdr.close();
        }
        catch(MalformedURLException mue)
        {
        }
        catch(HttpException he)
        {
        }
        catch(IOException ioe)
        {
        } 
    }
}

As you probably guessed, the real work of this example happens in the try-catch block. The first two lines set up the HttpURL object, which contains all of the connection information. Then we create a WebdavResource from the HttpURL, which connects to the server. After this, we create a File object to represent where we want the downloaded file to go. The getMethod() gets the file, and close() closes the connection. (Keep in mind that this is only an example, and the exception handling in this code is naive and can leave connections open.)

As you can see using WebdavResource is very straightforward and elegantly handles the various portions of the protocol. Changing this example to handle uploading a file is straightforward, as well. All we need to change are a few lines, as follows:

File fn = new File("local-file");
wdr.putMethod(fn);

Admittedly, changing the file name is superficial, but it is important to note that this line now needs to point to a local file as opposed to a remote file.

These examples are simplistic, but they illustrate how to use WebdavResource to access WebDAV servers. In the next section, we will explore a more complex example that will show how to use WebDAV's locking and unlocking features.

More Complex Examples

Let's say that we have a web site that is maintained by two teams of developers, separated by several time zones. Both teams have responsibility for editing HTML sources on a fairly static web site, and the site administrator wants to prevent them from simultaneously updating files and overwriting each other's changes (remember, this is an example; of course it would be better to use a version control system for this sort of application). In other words, we want to be able to upload, download, lock, and unlock files. We also want our locks to work between connections, in case we log out or are disconnected for whatever reason.

To facilitate this process, we want a class that handles:

  • Opening connections
  • Listing files
  • Locking files
  • Downloading files
  • Uploading files
  • Unlocking files
  • Closing connections

We already know how to open a connection, close a connection, upload a file, and download a file, so what we need is code to handle the locking, unlocking, and listing of files. We will assume that the class has an instance variable called wdr that is a WebdavResource and an instance variable path that is a String.

First, we want to be able to lock a file. We will do this with the lockMethod, as well as some other methods for error checking. You will also notice that we are setting the path of the WebdavResource to the file, which we did not have to do with the get and put methods. This is because certain methods, including isCollection, getPath, and setPath, are only supported if the current path is the file we want to work with. Others, like getMethod (but not getMethodData and getMethodDataAsString), do not support this interface. Yes, it is confusing at times.

Here is the code for locking a file:

public boolean lockFile(String filename)
    throws Exception
{
    // check to make sure current path is a
    // directory not a file make sure your initial
    // path contains a trailing "/" or else it is
    // considered a file!!

    if (!wdr.isCollection())
        throw new Exception("Path is currently a file");

    String currentPath = wdr.getPath();
    wdr.setPath(currentPath + "/" + filename);
    
    if (wdr.isLocked())
    {
        return false;
    }
    
    boolean returnVal = wdr.lockMethod();
    wdr.setPath(currentPath);
    return returnVal;
}

The unlockFile() method is identical, except that we call unlockMethod() on the WebdavResource.

Listing the files in the current directory is handled by the listFiles() method. Note in this example that again we check to make sure that we have the correct type of path.

public String[] listFiles () throws Exception
{
    if(!wdr.isCollection())
        throw new Exception ("Path is currently a file");
    return wdr.list();
}

Using these three methods as a base, adding methods that implement put, get, and/or post, we would have a fairly comprehensive class for interactively editing documents. Throw some Swing components on top of it, and you've got an interactive editing program.

Final Thoughts

Jakarta's Slide project makes adding WebDAV client functionality to Java applications a cinch. The libraries are open source, easy to use, and easy to integrate into all sorts of applications. While Slide's documentation leaves something to be desired, overall, Slide is a winner and makes adding WebDAV client capabilities to a Java programs a reality.

Andrew Anderson is a software developer and consultant in Chicago who's been using and programming on the Mac as long as he can remember.


Return to ONJava.com.