users@jersey.java.net

[Jersey] MessageBodyWriter and flushing

From: Mikael Ståldal <mikael.staldal_at_appearnetworks.com>
Date: Fri, 23 Jan 2015 17:07:37 +0100

I have a javax.ws.rs.ext.MessageBodyWriter like this:

@Provider
@Produces({MediaType.APPLICATION_JSON})
public class JsonMessageBodyWriter extends MessageBodyWriter<Object> {

  @Override
  public boolean isWriteable(Class<?> type, Type genericType, Annotation[]
annotations, MediaType mediaType) {
    return true;
  }

  @Override
  public long getSize(Object t, Class<?> type, Type genericType,
Annotation[] annotations, mediaType) {
    return -1;
  }

  public void writeTo(Object t, Class<?> type, Type genericType,
                      Annotation[] annotations,
                      MediaType mediaType,
                      MultivaluedMap<String, Object> httpHeaders,
                      OutputStream entityStream)
            throws java.io.IOException, javax.ws.rs.WebApplicationException
{

    OutputStreamWriter writer = new OutputStreamWriter(entityStream,
"UTF-8");

    // this will not flush() nor close() writer
    SuperCoolJsonLibrary.serializeObjectToWriter(t, writer);

    writer.flush(); // problem here
  }

}

I think I need to do something at the end of MessageBodyWriter.writeTo(),
otherwise there may be some data left buffered inside the
OutputStreamWriter. But OutputStreamWriter.flush() will flush the
entityStream I get from Jersey runtime a well, and that seems to cause this
problem for me:

http://w3facility.org/question/java-is-flush-needed-before-close-of-a-printwriter-buffer-stream/

How should this be done? OutputStreamWriter have a flushBuffer() method
which seems to do what I need, but it is not public :-(

I use Linux, Oracle JDK 1.8.0_20, jetty-9.0.3.v20130506, Jersey 2.15.

-- 
Mikael Ståldal
Chief Software Architect
*Appear*
Phone: +46 8 545 91 572
Email: mikael.staldal_at_appearnetworks.com