users@jersey.java.net

Re: [Jersey] Jersey 1.1 and implicit views

From: Owen Jacobson <owen.jacobson_at_grimoire.ca>
Date: Tue, 15 Dec 2009 18:30:19 -0500

Thanks for the feedback, Paul. Commentary inline below:

On Dec 15, 2009, at 4:05 AM, Paul Sandoz wrote:

> Hi Owen,
>
> Implicit views, as named, are implicitly implemented by Jersey, thus the only thing they can return as the model is the controller itself.

...

>> 2. What's the rationale behind passing the JAX-RS resource instance to the JSP as "it" rather than the value returned from the request handler method?
>
> The controller is the only thing that is consistently available to act as the model. There is no way, currently, for the controller to tell Jersey what the model should be for the set of implicit views (there can be a number of implicit views associated with the controller, where the name of the implicit view defines the path, with a special case for "index").

For every other type of view (eg. an XML view provided by JAXB, or a custom format from an @Provider implementation of MessageBodyWriter) the object used to generate the wire representation is the return value of the resource method used to process the request, no? So it's at least surprising (well, to me) that for an HTML view backed by a JSP Jersey passes some other object. If nothing else, I think this could do with more thorough documentation. I'm still not sure I understand why this is so.

May I assume that for

@Path("/hello")
public class Hello {
        @GET
        @Produces("application/xml")
        public HelloDocument getIndex() {
                return new HelloDocument();
        }
}

when Jersey decides to use an implicit JSP view that it will *never* invoke getIndex() itself, but instead only make the routing decision and then immediately forward to the appropriate JSP? I *think* that's what you're imply, and if so I can sort of see it.

I think this also means that implicit views interact badly with resources in the form

@Path("/hello")
public class Hello {
        @GET
        @Produces("application/xml")
        public Response getIndex() {
                return Response.ok(new HelloDocument()).build();
        }
}

in that the JSP controls things like the response status and headers, rather than the JAX-RS controller.

>>
>> 3. Is it possible to configure Jersey to pass the resulting HelloDocument bean to the JSP as "it", instead of the Hello instance?
>
> Yes, but you have to turn the implicit view into an explicit view. But as a consequence you loose the prioritization feature and will need to "normalize" the accept header.

Looking closer at the Accept: header Safari &c generate, I'm tempted to call this a UA bug rather than a surprising Jersey behaviour. From the bookstore app's header dumper, Accept = [application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5] suggests Safari is actually preferring XML (or XHTML) over HTML, which is... creative. I might investigate using client-side XSLT for the UI version instead of server-side (JSP) HTML rendering, as much as I shudder at the thought.

How hard is writing a MessageBodyWriter that delegates to JSP? It seems like that might be a better map for what I want to do (and more portable between JAX-RS implementations, to boot): I only want the JSP engine to convert the response entity object (either the resource itself, the return value from a resource method, or the entity associated with a Response object returned by a resource method) into a representation. I don't want JSP to handle the bulk of the request.

> For implicit views to work in conjunction with resource methods views you need to do something like the following:
>
> @Path("/hello")
> @ImplicitProduces("text/html;qs=5")
> public class Hello {
> @GET
> @Produces("application/xml")
> public HelloDocument getXml() {
> return new HelloDocument();
> }
> }
>
> The view can then access the property "index" to obtain the HelloDocument instance. Note the "qs" parameter on the @ImplicitProduces value. The "qs" value is multiplied by the "q" value in the accept header thus the server is biasing to return text/html over application/xml.
>
> See the bookstore sample for such cases:
>
> http://download.java.net/maven/2/com/sun/jersey/samples/bookstore/1.1.4.1/bookstore-1.1.4.1-project.zip

Ah, thanks.

I'd been looking at a pre-1.0 version of the bookstore, which left me with a few other head-scratchers. It seems the link where I downloaded it from now points to the 1.0.3 samples bundle; I hadn't found an obvious 1.1 samples download link in the docs.

Cheers,
-o