users@jersey.java.net

Re: [Jersey] Re: Why doesn't HttpRequestContext expose request attributes?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 06 Nov 2009 18:12:37 +0100

On Nov 6, 2009, at 5:04 PM, Paul Sandoz wrote:

>
> On Nov 6, 2009, at 5:02 PM, Joe Bradley wrote:
>
>> Thanks Paul. I tried this but it doesn't seem to be working and
>> it's not obvious to me why not. The Jersey runtime discovers the
>> RequestAttributeInjector as a provider and constructs it, but the
>> getInjectable method is never called. I'm using the
>> RequestAttribute annotation in my resource class exactly has you
>> have it below.
>>
>> Any ideas?
>>
>
> Not sure, i wrote the code directly in the email without testing,
> let me try a simple example.
>

I hacked the hello world web app sample and it worked, see below for
the code.

Paul.

package com.sun.jersey.samples.helloworld.resources;

import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.api.core.ResourceContext;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Type;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;

import javax.ws.rs.ext.Provider;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

// The Java class will be hosted at the URI path "/helloworld"
@Path("/helloworld")
public class HelloWorldResource {

     // The Java method will process HTTP GET requests
     @GET
     // The Java method will produce content identified by the MIME
Media
     // type "text/plain"
     @Produces("text/plain")
     public String getClichedMessage() {
         // Return some cliched textual content
         return "Hello World";
     }

     @Path("x")
     public Foo get(@Context ResourceContext rc, @Context
HttpServletRequest r) {
         r.setAttribute("foo", new Integer(1111111));
         return rc.getResource(Foo.class);
     }

     public static class Foo {
         @RequestAttribute("foo") Integer i;

         @GET
         public String get() {
             return "" + i;
         }
     }

     @Target({FIELD, PARAMETER, METHOD})
     @Retention(RUNTIME)
     @Documented
     public static @interface RequestAttribute {
         String value();
     }

     @Provider
     public static class RequestAttributeInjector implements
InjectableProvider<RequestAttribute, Type> {

         private final HttpContext c;
         private final HttpServletRequest r;

         public RequestAttributeInjector(@Context HttpContext c,
@Context HttpServletRequest r) {
             this.c = c;
             this.r = r;
         }

         public ComponentScope getScope() {
             return ComponentScope.PerRequest;
         }

         public Injectable getInjectable(ComponentContext ic,
RequestAttribute a, final Type t) {
             final String name = a.value();

             return new Injectable() {
                 public Object getValue() {
                     Object o = c.getProperties().get(name);
                     if (o == null) {
                         o = r.getAttribute(name);
                     }
                     if (o == null) {
                         // Throw exception or return null?
                     }

                     // TODO verify that o.getClass() is compatible
with Type t
                     return o;
                 }
             };
         }
     }
}