users@jersey.java.net

Re: [Jersey] Trying to include a resource class from jsp

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 09 Dec 2009 11:33:19 +0100

Hi Yoryos,

I am very sorry i have not had enough time to look in detail. I
require a 2 to 4 hour slot of free time to really think about this :-(

Here off the top of my head is how the Viewable is processed:

1) A Viewable is returned from a resource method;

2) The Viewable in 1) is processed by
com.sun.jersey.server.impl.template.ViewableMessageBodyWriter

3) The ViewableMessageBodyWriter code is as follows:

     @Context HttpContext hc;

     @Context UriInfo ui;

     @Context TemplateContext tc;

     public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
         return Viewable.class.isAssignableFrom(type);
     }
     public void writeTo(Viewable v,
             Class<?> type, Type genericType, Annotation[] annotations,
             MediaType mediaType, MultivaluedMap<String, Object>
httpHeaders,
             OutputStream entityStream) throws IOException {
         final ResolvedViewable rv = resolve(v);
         if (rv == null)
             throw new IOException("The template name, " +
                     v.getTemplateName() +
                     ", could not be resolved to a fully qualified
template name");

          
hc.getProperties().put("com.sun.jersey.spi.template.ResolvedViewable",
rv);
         rv.writeTo(entityStream);
     }

     private ResolvedViewable resolve(Viewable v) {
         if (v instanceof ResolvedViewable) {
             return (ResolvedViewable)v;
         } else {
             return tc.resolveViewable(v, ui);
         }
     }

4) The TemplateContext is used to to transform the Viewable into a
ResolvedViewable, see:

  https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/spi/template/TemplateContext.html
#resolveViewable%28com.sun.jersey.api.view.Viewable,
%20javax.ws.rs.core.UriInfo%29

The above method is implemented by TemplateFactory:

     public ResolvedViewable resolveViewable(Viewable v, UriInfo ui) {
         if (v.isTemplateNameAbsolute()) {
             return resolveAbsoluteViewable(v);
         } else if (v.getResolvingClass() != null) {
             return resolveRelativeViewable(v, v.getResolvingClass());
         } else {
             final List<Object> mrs = ui.getMatchedResources();
             if (mrs == null || mrs.size() == 0)
                 throw new TemplateContextException("There is no last
matching resource available");

             return resolveRelativeViewable(v, mrs.get(0).getClass());
         }
     }


5) Then the resolved viewable writes itself out to the output stream:

     public void writeTo(OutputStream out) throws IOException {
         template.writeTo(getTemplateName(), getModel(), out);
     }

which defers to the TemplateProcessor that resolved the Viewable.

I recommend doing a debug session tracing through the steps.

Paul.

On Dec 6, 2009, at 9:34 AM, Yoryos wrote:

> Hello all,
> I'm trying to make jersey be able to handle included requests. That
> means that having a jsp to be able to include a uri that maps to a
> resource class. Of course the resource class should be able to
> produce html.
>
> I'm using the jersey filter. So the first thing I've done was to let
> the Servlet container use the jersey filter not only for the actual
> requests but also for the forwarding and included ones. This can be
> done by adding the following to the mapping of the filter at web.xml:
> <dispatcher>REQUEST</dispatcher>
> <dispatcher>FORWARD</dispatcher>
> <dispatcher>INCLUDE</dispatcher>
>
> This didn't work out of the box. So I had to take a look at the
> source in order to have a better view of what is going on. Looking
> at the source of jersey, I found that ServletContainer class does
> not handle included requests at all. So I had also to fix that too.
> I've posted the code on a previous email and also created an issue (https://jersey.dev.java.net/issues/show_bug.cgi?id=432
> ) with a maven project with a working solution.
>
> A working solution means that you can include a resource class with
> in jsp and get html that you would have calling only the uri that
> maps to the included class.
>
> With a modified filter you will be able to just include resource
> classes without any model as jersey binds the model always to 'it'
> at the request scope. To overcome this I had to also modify a little
> bit the default default jsptemplate and instead of binding the model
> to 'it', bind it to something like
> '[ResourceClass.getClass().getSimpleName()]Model'
>
> The above solution does not require to change Jersey's sources and
> works ok but it is not the best one. I mean the user should be able
> to define the name of the model at the request scope if he wants to
> and it would be nice to be able to have an annotation for methods
> that should return only results of type Viewable and it will be
> called only when the resource is about to be included.
>
> This is where I would like some help. Can someone explain the exact
> procedure of serving a Resource class with a Viewable because I'm
> pretty lost when tried to read the source. At least from where
> should I start reading.
>
> I hope I described ok the whole situation!
>
> Yoryos