users@jersey.java.net

[Jersey] Re: MessageBodyWriter and flushing

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 13 Feb 2015 17:54:01 +0100

Why don't you then just create your own output stream wrapper that overrides the flush() method to do nothing (and delegate other methods to the wrapped output stream) and then just create an OutputStreamWriter, serialize into it and invoke flush() on writer? That will make sure that StreamEncoder will flush the buffer into your stream, and your stream will ensure that flush() call does not get propagated. IOW:

public class NonFlushingOutputStream extends FilterOutputStream {
    public NonFlushingOutputStream(OutputStream out) {
        super(out);
    }
    public void flush() throws IOException {
        // no flushing...
    }
}

...

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(new NonFlushingOutputStream(entityStream), "UTF-8");


    SuperCoolJsonLibrary.serializeObjectToWriter(t, writer); // ehm... really supercool??

    writer.flush(); // just flush the buffer of the internal StreamEncoder in the OutputStreamWriter
}


Marek

> On 28 Jan 2015, at 18:54, Mikael Ståldal <mikael.staldal_at_appearnetworks.com> wrote:
>
> Yes, but how can I accomplish that when I need to wrap the OutputStream with a Writer?
>
> On Wed, Jan 28, 2015 at 6:41 PM, Marek Potociar <marek.potociar_at_oracle.com> wrote:
> IMO, you should not be flushing anything and just let the framework flush the content for you once it is done processing the outbound message…
>
> Marek
>
>> On 23 Jan 2015, at 17:07, Mikael Ståldal <mikael.staldal_at_appearnetworks.com> wrote:
>>
>> 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
>
>
>
>
> --
> Mikael Ståldal
> Chief Software Architect
> Appear
> Phone: +46 8 545 91 572
> Email: mikael.staldal_at_appearnetworks.com