users@jsr311.java.net

Re: Optimizing MessageBodyWriterS

From: Reto Bachmann-Gmür <reto.bachmann_at_trialox.org>
Date: Thu, 29 Jan 2009 20:13:43 +0100

Hi Paul

The API doc says that the method returns -1 if the length /cannot/ be
determined in advanced. As for normal content the length can always be
determined I thought that only for streaming sources or
comet-applications the method would have to return -1. Without
considering the possibility of implementations doing some buffering to
determine the length or doing chunked encoding, I assumed -1 would
render Keep-Alive impossible.

Would it make sense for the writer to tell the implementation that the
implementation should determine the length itself, that is the response
is finite and short and no purposeful interruption (such as with
server-push) will happen when writing to the stream?

Reto




Paul Sandoz said the following on 01/29/2009 01:05 PM:
> Hi Reto,
>
> My approach has been to only implement get size iff it is known in
> advanced (e.g. File size). I consider it more of a hint to the HTTP
> container to know whether it can use a Content-Length with that value
> instead of:
>
> 1) using chunked transfer encoding;
>
> 2) buffering the content to determine the length; or
>
> 3) closing the connection after the response entity has been written.
>
> I think the HTTP container should determine the best strategy of one
> of the three above and the writers do not need to be involved in such
> details.
>
> If getSize returns a value > -1 then that value should be equal to the
> value that is number of bytes that are written to the OutputStream of
> the writeTo method for the same parameter values passed to both methods.
>
> Paul.
>
> On Jan 29, 2009, at 9:41 AM, Reto Bachmann-Gmür wrote:
>
>> 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
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: users-help_at_jsr311.dev.java.net
>