users@jsr311.java.net

Optimizing MessageBodyWriterS

From: Reto Bachmann-Gmür <reto.bachmann_at_trialox.org>
Date: Thu, 29 Jan 2009 09:41:37 +0100

Hello

I'm wondering what the best practice to write MBWs is. In my experience
the getSize and the writeTo method often have very similar code, or the
getSize-method looks similar to this:

    @Override
    public long getSize(GraphNode node, Class<?> clazz, Type t,
Annotation[] as,
            MediaType m) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            writeTo(node, clazz, t, as, m, null, baos);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        } catch (WebApplicationException ex) {
            throw new RuntimeException(ex);
        }
        return baos.size();
    }

One optimization might be to cache the resulting object- bytes mapping
(in a ThreadLocal weak reference of a WeakHashMap) so that when the
implementation invokes writeTo, the already computed bytes can be
written to the OutputStream.

Another approach could be to return an estimate of the size or -1 in the
getSize method, and set the exact Content-Length to the headers-map when
writeTo is invoked.

Another issue is when the rendering of the object could change between
invocation of getSize and writeTo. The class GraphNode represents a node
in a graph (which is occasionally modified), the writers for different
media-types expand the neighborhood of the node to different depths so
that it would be awkward to do this expansion in the resource method and
return a value-object. I think in such a scenario the writeTo method
must either write the bytes pre-computed on invocation of getSize or
(re)set the Content-Length header.

Cheers,
Reto