1. How to use it

    Milton is designed to be embedded into your web application. It comes with a few front ends, each of which is just a thin wrapper on milton's core class - HttpManager.
    The most common way of using milton is to add the MiltonServlet to you web.xml. But there are also a couple of Spring specific front ends such as a SpringAwareMiltonServlet and a Spring MVC controller.
    These front end classes are in milton-servlet, and the core API and HttpManager are in milton-api
     
  2. Resource API

    The Milton jar is designed to be a protocol handler. It simply interprets the HTTP protocol (with webdav extensions) and portrays it as a series of java interfaces.

    Milton is agnostic about the nature of your data. You simply implement the interfaces needed for it to locate your resources, and those resources.

    Milton is also agnostic about your runtime container. It was specifically designed to not depend on the Servlet API. Instead, a seperate library called MiltonServlet provides that integration. But Milton could equally be used from any other web container such as SimpleWeb or xLightWeb

    As part of not depending on the Servlet API, Milton has its own support for Filters.

    Webdav has no concept of sessions, and webdav clients usually don't implement any of the session mechanisms used by browsers. So Milton has no explicit support for sessions or cookies. However, if you use MiltonServet you can access the underlying request and response objects by casting the request to ServletRequest and calling getRequest
  3. Model

    The HTTP specification and webdav extensions are written in terms of actions on and attributes of resources. So it makes sense to model our API along the same lines.

    The central concept to Milton is Resource. This interface is extended for each HTTP method with methods to support that method. You can choose which http methods to allow on your data by choosing which Milton Resource interfaces to implement. If a request is made which is not supported Milton will respond with the Method-Not-Allowed status.

    This approach includes getting the content of a resource. This is done by implementing GetableResource and mostly involves implementing sendContent. You can implement this method with anything that can write to an OutputStream. This includes including JSP's, Velocity and Freemarker templates, XSLT transformations and directly writing.
  4. Non Servlet Containers

    The core milton library doesnt reference the Servlet API so can easily be integrated into non servlet http and webdav applications. See here for details.

  5. HTTP Methods and Milton Interfaces

    Your Resource implementation must implement the appropriate interface to support an HTTP method. Its completely appropriate to not implement any method if you do not want to support the method. Only supported methods will be returned by OPTION, Milton does this determination by doing an instanceof on your Resource for each of these.

    For example, if you have a resource which cannot be physically deleted under any circumstances it should not implement DeletableResource.

    Method Supporting Interface
    OPTION Resource
    GET GetableResource
    HEAD GetableResource
    POST PostableResource
    PUT PutableResource
    PROPFIND PropFindableResouce
    MKCOL MakeCollectionableResource
    DELETE DeletableResource
    COPY CopyableResource
    MOVE MoveableResource
    Lock LockableResource
       

  6. Content Types


    The CollectionResource.createNew method simply passes along the content type supplied in the PUT header. but unfortunately, most webdav clients don't seem to send it

    i usually use the MimeUtil utilities for determining the content type. the milton-filesystem library demonstrates it. but since there's no where to store an explicit content type in a file system the content type supplied in the PUT (if any) is ignored and we calculate the content type dynamically in the getContentType method in FsFileResource like this:

            Collection mimeTypes = MimeUtil.getMimeTypes( file );
            StringBuffer sb = null;
            for( Object o : mimeTypes ) {
                MimeType mt = (MimeType) o;
                if( sb == null) {
                    sb = new StringBuffer();
                } else {
                    sb.append( ",");
                }
                sb.append(mt.toString());
            }
            if( sb == null ) return null;
            String mimeTypes = sb.toString();



    if you're using a JPA data store you can calculate and then store the content-type(s) instead.

    One issue with MimeUtils is that the interface requires a File to do mime detection based on extension, but you might not have a physical file object. it should be straight forward to hack it to take an explicit file extension. Or you can just rely on the methods that take an input stream, but they miss some really import mime types such as text/plain.

    Note that MimeUtils actually gives you a list of mime types - the getContentType method should select the 'best' one given the possibilities in the "accepts" header like this:

            MimeType mt = MimeUtil.getPreferedMimeType(preferredList, mime);
            return mt.toString();
     
  7. Response Handling

    Milton allows different response handlers to be plugged in to support different requirements. The currently provided response handlers are:
    - DefaultResponseHandler: supports a wide variety of client applications. Defaults supported-levels to "1" meaning that by default locking is disabled.
    - CompressingResponseHandler: wraps another response handler to add gzip compression of textual types, if supported by the user agent
    - MsOfficeResponseHandler: tweaks the wrapped response handler to support MS office. This is simply to report 'method not allowed' conditions as 'method not supported'
     
  8. Security

    See the security page.
  9. Transactions

    Milton can be used with transactional databases. To use transactions successfully you should ensure that each request is an atomic transaction. DO NOT assume that a call to a method like createCollection will be a single transaction as there are cases where milton will perform several such operations in a single request, and they must all be rolled back together if an error occurs.
  10. Custom Properties

    Custom properties are properties which can be read and written in PROPFIND and PROPPATCH requests, and are defined by WEBDAV or other specs. Milton supports a few different ways to use custom properties:
    a. Implement your own PropertySource and inject it into PropertySourceList
    b. Your resource implements CustomPropertyResource
    c. Put the BeanPropertyResource annotation on your resource class.

     
  11. Miscellany

HTML link to open webdav:

 




http://localhost:8080/webdav/webdav.odt";

FOLDER =  "http://localhost:8080/webdav";

TARGET = "_blank"

>

Open in Web Folder View





This works with the Tomcat webdav sample app. Only Vista requires you to map 

the folder as a web folder, but this is something I can live with.