users@jersey.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 11 Dec 2009 16:10:14 +0100

Hi Yoryos,

I still need to look in greater detail, but what occurs to me is one
might require a stack-based solution where for each include where "it"
is pushed on the stack and then popped off, since a view could include
another view and so on.

It would be good if we can find a solution without having to modify
Viewable or having to define additional semantics on resource classes
as i think such solutions break the layering.

To support this it might require that we introduce a new tag. Much
like Jersey has its own include tag for including other JSPs using the
resource class to find a suitable JSP we might be able to do something
similar for the inclusion of views of other resources.

So i recommend taking a closer look at:

   com.sun.jersey.server.impl.container.servlet.Include

Paul.

On Dec 11, 2009, at 9:06 AM, Yoryos wrote:

> Ok, thank you! I'll try to work on that this weekend! As a first
> solution on my mind would be to have Viewable to be able to have
> another String property with a default value 'it', that can be
> defined at the initialization of the class. Then we can use it's
> value instead of a 'it' to bind the model to the request scope at
> the RequestDispatcheWrapper (I don't remember the exact name). I'll
> have a closer look though!
>
> Yoryos
>
>
> On Wed, Dec 9, 2009 at 12:33, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> 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
>
>