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