dev@jsr311.java.net

Re: JSR311: Response isn't adequate

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 26 Feb 2008 10:49:50 +0100

Bill Burke wrote:
>
>
> Paul Sandoz wrote:
>> Bill Burke wrote:
>>> It seems we have no access to an OutputStream. I can see the need
>>> for wanting to stream back to the client a DB's Blob or Clob.
>>>
>>
>> https://jsr311.dev.java.net/issues/show_bug.cgi?id=6
>>
>> Two workarounds:
>>
>> - develop a message body writer for the Blob/Clob; or
>>
>> - if the Blob/Clob is accessed as an InputStream one can return that.
>>
>
> This is impossible as you need to have the JDBC connection/resultset
> open IIRC.
>

I suppose the InputStream.close() can do this. The message body writer
for InputStream should close the stream after all bytes have been
written, or an exception occurs (we need to specify that behaviour). But
i can see why this can be error prone...


>> Do you have any proposed suggestions on how to achieve the committing
>> of meta-data and writing to an OutputStream?
>>
>
> Headers have to be written before data, correct?

Yes, we don't want to buffer!


> Then enforce that
> ordering. IIRC, Servlet spec enforces commit errors.
>
> meta-data a.k.a. MultivaluedMap<String, Object> can just transform on a
> put, add, whatever and write directly to the response (i.e.
> HttpServletResponse)
>
> I think the Servlet spec has done a pretty good job on what the
> abstraction should be. We just need to refactor HTtpServletResponse to
> gut all the junk.
>

The RI does support writing to an OutputStream. When the first byte is
written to a stream the HTTP status code and headers are committed. But
it exposes a RI specific HTTP response abstraction that i wanted to
avoid propagating to the 311 API [*].

It would be nice if we could still use the response building mechanism.
Perhaps something like the following that extends OutputStream:

   public abstract ResponseOutputStream extends OutputStream {
     // Any entity set on Response will be ignored.
     public abstract void setResponse(Response r);
   }

the type of which can be declared as a method parameter (the runtime
chooses the concrete implementation):

   @POST
   void post(InputStream in, ResponseOutputStream out) {
      // Consume the request as a stream
      in.read(...);

      // Produce the response as a stream
      Response r = Response.created(URI.create("relative")).build();
      out.setResponse(r);
      out.write(...);
   }

the method signature of such methods is required to return void (or one
could ignore what is returned). And the exception handling when a
response is committed needs to be different (sigh... i would prefer to
return a closure that does the writing...)

Paul.

[*] i really do wish there were a set of reusable HTTP request/response
interfaces that could be shared across HTTP frameworks.

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109