dev@jersey.java.net

Re: [Jersey] HttpContext does not return the MediaType

From: Paul Sandoz <Paul.Sandoz_at_oracle.com>
Date: Tue, 7 Sep 2010 16:10:08 +0200

On Sep 7, 2010, at 2:32 PM, exxos wrote:

> Thank you very much for this clarification.
>
> Implicitly behind this, there is still the need to determine which
> is the MediaType to return ?
>

Yes.


> I understand that it is done automatically most of time by Jersey:
>
> For example, if you are in the Resource method that produces "xml"
> or "json".
> The developper has nothing to deal with. The correct @Provider will
> be called automatically by Jersey,
> in order to decide the correct representation of the entity to return.
>

Yes.


> But the issue more for HTML reprsentations, that are made via a
> Viewable wrapper.
>
> Rarely for Resource method but truly for ExceptionMappers:
> And the music sounds like this:
>
> Resonse toResponse() {
> MediaType firstType =
> httpContext.getRequest().getAcceptableMediaTypes().get(0);
> if(firstType.equals(MediaType.TEXT_HTML)) {
> response = new Viewable("/jsp",entity);
> }
> }
>
> This is what happens (often) in a ExceptionMapper that need to deal
> with many represenations.It does not know the @Procuces constraint
> of the Resource method where the issue has occurred.
>

Nor if the exception was thrown from a resource method. For example it
could be thrown from a constructor, a sub-resource locator or a filter.

There is currently no support for @Produces on an ExceptionMapper,
which could potentially help. But i am not sure about that since
message body writers can do that, although accept that does not work
too well for Viewable. Generally responses to 4xx or greater don't
have to obey the same constraints as 2xx responses for acceptable
content. For example, what content should one return for a 406 (Not
Acceptable) response?

A different work around is to use variants for the set of media types
that support error responses:

List<Variant> vs = Variant.mediaTypes("text/html", "application/xml",
"application/json");
Variant v = request.selectVariant(vs);

Jersey does add the content-type it will set, if concrete, to the
request property:

    "com.sun.jersey.server.impl.uri.rules.HttpMethodRule.Content-Type",

i could make that public property and then you can look that up. But i
think it may be better to solve this by enabling access to the content-
type and relaxing the reseting constraints.

Paul.


> Or may be I missed something...
>

> Regards,
> exxos.
>
>
>
> On Tue, Sep 7, 2010 at 1:45 PM, Paul Sandoz <Paul.Sandoz_at_oracle.com>
> wrote:
> Hi,
>
> It is because the response content-type header is only set after the
> response of the resource method has been processed.
>
> For the case of exceptions thrown from the resource method then the
> content-type will be set after the response of the exception mapper
> has been returned.
>
> I am gonna have to think of a way to improve the situation as a
> number of developers are running into this issue. The problem is
> when one sets a Response instance on the HttpResponseContext
> (returned or generated from the resource method or an exception
> mapper) existing response headers, if any, are removed i.e. it
> replaces the complete response state.
>
> If one explicitly sets response headers in a resource method one may
> not necessarily want them to apply if an exception is thrown from
> that resource method.
>
> Another example is if an exception occurs in a response filter,
> which is then mapped to a response, then it does not make sense to
> apply the content-type (nor most likely any other response headers
> set by other filters) associated with the resource method.
>
> I need to think some more on this...
>
> Paul.
>
>
> On Sep 7, 2010, at 1:03 PM, exxos wrote:
>
> Hello,
>
> Here is the code I'm testing:
>
> @Path("hello")
> public class App {
>
> @Context HttpContext httpContext;
>
> @GET
> @Produces(MediaType.TEXT_HTML)
> public Response getHtml() {
>
> System.out.println("RESOURCE hello >>> HttpContext Response:"
> + httpContext.getResponse());
> System.out.println("RESOURCE hello >>> MediaType :" +
> httpContext.getResponse().getMediaType());
>
> return Response.ok("Hello I'm fine !").build();
> }
> }
>
> The issue is that MediaType is "null". Could you please advise why I
> cannot get the MediaType from the HttpContext?
> (This is the same behavior with ExecptionMapper where I base content
> negotiation on that)
>
> Best regards,
> exxos.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
>
>