users@jersey.java.net

Re: [Jersey] StreamingOutput, multipart and boundary parameter

From: Jan Algermissen <algermissen1971_at_mac.com>
Date: Thu, 01 Oct 2009 14:06:09 +0200

Paul,

I am using 1.1.2 (I think - maybe I am misunderstanding Maven, though
and Jetty).

It worked before (today) but maybe Maven has updated a dependency when
building,?

I figured out that what happens is that the Resource class is being
returned as a string, IOW, the server sends back the class name. This
is independent of your code snippet.

Thanks anyway and don't bother. Seems to be something else.

Jan



On Oct 1, 2009, at 1:48 PM, Paul Sandoz wrote:

>
> 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
>>
>

--------------------------------------
Jan Algermissen

Mail: algermissen_at_acm.org
Blog: http://algermissen.blogspot.com/
Home: http://www.jalgermissen.com
--------------------------------------