users@jersey.java.net

Re: [Jersey] Jersey 1.1 and implicit views

From: <FSauer_at_dsthealthsolutions.com>
Date: Tue, 15 Dec 2009 17:46:21 -0600

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

I solved this problem by adding a ContainerRequestFilter that looks at the
various messed up Accept headers and "fixes" them... IE sends */*, like it
really does not care what you give it !

this filter looks something like this:

public class AcceptHeaderNormalizer implements ContainerRequestFilter {

        public ContainerRequest filter(ContainerRequest request) {
                String agent = request.getHeaderValue("User-Agent");
                String accept = request.getHeaderValue("Accept");
                if (agent == null || accept == null) return request;
                if (agent.contains("MSIE") && !accept.equals(
"application/json")) {
                        request.getRequestHeaders().putSingle("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
                } else if (agent.contains("Safari")) {
                        request.getRequestHeaders().putSingle("Accept"
,accept.replace("application/xml,application/xhtml+xml,text/html;q=0.9",
"text/html,application/xhtml+xml,application/xml;q=0.9"));
                }
                return request;
        }
}


Frank






Owen Jacobson <owen.jacobson_at_grimoire.ca>
12/15/2009 05:30 PM
Please respond to
users_at_jersey.dev.java.net


To
users_at_jersey.dev.java.net
cc

Subject
Re: [Jersey] Jersey 1.1 and implicit views






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
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
For additional commands, e-mail: users-help_at_jersey.dev.java.net




-----------------------------------------
Please consider the environment before printing this email and any
attachments.

This e-mail and any attachments are intended only for the
individual or company to which it is addressed and may contain
information which is privileged, confidential and prohibited from
disclosure or unauthorized use under applicable law. If you are
not the intended recipient of this e-mail, you are hereby notified
that any use, dissemination, or copying of this e-mail or the
information contained in this e-mail is strictly prohibited by the
sender. If you have received this transmission in error, please
return the material received to the sender and delete all copies
from your system.