users@jersey.java.net

Re: [Jersey] StreamingOutput, multipart and boundary parameter

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 01 Oct 2009 13:48:21 +0200

On Oct 1, 2009, at 1:39 PM, Jan Algermissen wrote:

> Paul,
>
> I now have
>
>
> @GET @Produces("multipart/mixed")
> public StreamingOutput getResource(
> final @Context HttpContext hc, // Jersey specific class
> @PathParam("worksetId") String worksetId,
> @PathParam("timestamp") String timestamp
> ) {
> return new StreamingOutput() {
> public void write(OutputStream outputStream) {
>
> // This will be null if there is no @Produces
> MediaType ct = hc.getResponse().getMediaType();
>
> // Set media type with boundary
> Map<String, String> parameters = new HashMap<String, String>();
> parameters.put("boundary", "abc");
> MediaType entityMediaType = new MediaType("multipart", "mixed",
> parameters);
>
> hc.getResponse().getHttpHeaders().putSingle("Content-Type",
> entityMediaType);
>
> //
> hc.getResponse().getHttpHeaders().remove("Content-Length");
>
> PrintWriter out = new PrintWriter(outputStream);
> out.println("___AAAAA");
> out.println("BBBB");
> out.close();
> } };
> }
>
>
> The media type is not changed to contain a boundary and the server
> insists on content-length 0.
>

I just copied the code you have presented above and pasted into the
simple hello world web app sample (made some mods to remove the path
parameters) and it worked fine (see end of email).

What version of Jersey are you using? and what HTTP container are you
using?

Paul.


     @Path("x")
     @GET
     @Produces("multipart/mixed")
     public StreamingOutput getResource(
             final @Context HttpContext hc) {
         return new StreamingOutput() {

             public void write(OutputStream outputStream) {

                 // This will be null if there is no @Produces
                 MediaType ct = hc.getResponse().getMediaType();

                 // Set media type with boundary
                 Map<String, String> parameters = new HashMap<String,
String>();
                 parameters.put("boundary", "abc");
                 MediaType entityMediaType = new
MediaType("multipart", "mixed", parameters);
                 hc.getResponse().getHttpHeaders().putSingle("Content-
Type", entityMediaType);

                 PrintWriter out = new PrintWriter(outputStream);
                 out.println("___AAAAA");
                 out.println("BBBB");
                 out.close();
             }
         };
     }


# curl -v http://localhost:8080/helloworld-webapp/helloworld/x
* About to connect() to localhost port 8080 (#0)
* Trying ::1... Connection refused
* Trying fe80::1... Connection refused
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /helloworld-webapp/helloworld/x HTTP/1.1
> User-Agent: curl/7.16.3 (powerpc-apple-darwin9.0) libcurl/7.16.3
OpenSSL/0.9.7l zlib/1.2.3
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Servlet/2.5
< Server: GlassFish/v3
< Content-Type: multipart/mixed;boundary=abc
< Content-Length: 14
< Date: Thu, 01 Oct 2009 11:45:11 GMT
<
___AAAAA
BBBB
* Connection #0 to host localhost left intact
* Closing connection #0


> Seems I am doing something stupid, but I have no idea what.
>
> I will want to remove the content-length altogether but this does
> not seem possible either.
>
> Thanks,
>
> Jan
>
>
>
>
>
>
>
>
>
> On Oct 1, 2009, at 12:44 PM, Paul Sandoz wrote:
>
>>
>> On Oct 1, 2009, at 12:35 PM, Jan Algermissen wrote:
>>>
>>>
>>>>
>>>> If you are not using a message body writer you can set the media
>>>> type in a returned Response instance e.g. if you are using an
>>>> instance of StreamingOutput for the entity.
>>>>
>>>> Paul.
>>>>
>>>> // Determine the boundary string to be used, creating one if
>>>> needed
>>>> MediaType entityMediaType = (MediaType)
>>>> headers.getFirst("Content-Type");
>>>> if (entityMediaType == null) {
>>>> Map<String, String> parameters = new HashMap<String,
>>>> String>();
>>>> parameters.put("boundary", createBoundary());
>>>> entityMediaType = new MediaType("multipart", "mixed",
>>>> parameters);
>>>> headers.putSingle("Content-Type", entityMediaType);
>>>> }
>>>> String boundaryString =
>>>> entityMediaType.getParameters().get("boundary");
>>>> if (boundaryString == null) {
>>>> boundaryString = createBoundary();
>>>> Map<String, String> parameters = new HashMap<String,
>>>> String>();
>>>> parameters.putAll(entityMediaType.getParameters());
>>>> parameters.put("boundary", boundaryString);
>>>> entityMediaType = new MediaType(entityMediaType.getType(),
>>>> entityMediaType.getSubtype(),
>>>> parameters);
>>>> headers.putSingle("Content-Type", entityMediaType);
>>>> }
>>>>
>>>
>>> I think I will use a MessageBodyWriter but anyway, if I don't -
>>> where would I put the code you sent? at the beginning of the write
>>> method?
>>>
>>> public StreamingOutput getResource(
>>> @PathParam("id") String id
>>> ) {
>>> return new StreamingOutput() {
>>> public void write(OutputStream outputStream) {
>>> // PUT CODE HERE???
>>> PrintWriter out = new PrintWriter(outputStream);
>>> out.println("Foo");
>>> out.close();
>>> } };
>>> }
>>>
>>
>> You could do:
>>
>> public Response getResource(...) {
>> MediaType m = ... // create media type with boundary string
>>
>> StreamingOutput o = ...
>>
>> return Response.ok(o, m).build();
>> }
>>
>>
>> Or:
>>
>> public StreamingOutput getResource(
>> final @Context HttpContext hc, // Jersey
>> specific class
>> @PathParam("id") String id
>> ) {
>> return new StreamingOutput() {
>> public void write(OutputStream outputStream) {
>> // This will be null if there is no @Produces
>> MediaType ct =
>> hc.getResponse().getMediaType();
>> // Set media type with boundary
>> MediaType ctWithBoundary = ...
>>
>> hc.getResponse().getHttpHeaders().put("Content-Type",
>> ctWithBoundary);
>>
>> PrintWriter out = new PrintWriter(outputStream);
>> out.println("Foo");
>> out.close();
>> } };
>> }
>>
>> Paul.
>>
>
> --------------------------------------
> Jan Algermissen
>
> Mail: algermissen_at_acm.org
> Blog: http://algermissen.blogspot.com/
> Home: http://www.jalgermissen.com
> --------------------------------------
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>