javakaffee

Just another weblog about (web) development technologies like spring, tapestry, jersey, jsf, hibernate and more

March 8, 2008

Jersey is fun - exploring RESTful webservices - subtitle: @Springify your resources

Filed under: development, java, webdev, REST — martin.grotzke @ 6:14 am

Hi,

my last post is nearly years ago and of course I wanted to write about this and that. But right now I had so much fun that I have to share this.

Fun with… jersey, the reference implementation of the upcoming jsr311 that specifies how to build RESTful web services in java.

Now I was just playing around with jersey and had a look at the sources and found out how easy it is to define an annotation and inject spring beans based on this annotation. The spring integration itself is described here, it shows a SpringServlet that loads beans based on the class from springs application context.

Now the part that made me happy:

First you define an annotation @SpringBean:


@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface SpringBean {

}

Then, in your SpringServlet you implement a base SpringInjectable for springified beans (of course you can make this public, but’s it’s not that important, just for conveniance…):


    private static abstract class SpringInjectable<V> extends Injectable<SpringBean, V> {
        public Class<SpringBean> getAnnotationClass() {
            return SpringBean.class;
        }
    }

and finally register the spring beans that you want to publish to your resource classes within a method like this (still in the SpringServlet):


    protected void initiate(ResourceConfig rc, WebApplication wa) {
        // get spring's applicationContext
        ApplicationContext springContext = WebApplicationContextUtils.
                getRequiredWebApplicationContext(getServletContext());
        // register your spring beans - this is new
        addInjectables( wa, springContext, SpringService1.class, SpringService2.class ); 
        // now let jersey do the rest
        wa.initiate(rc, new SpringComponentProvider(springContext));
    }

    private void addInjectables( WebApplication wa, final ApplicationContext springContext, Class<?> ... injectables ) {
        for ( final Class<?> injectable : injectables ) {
            wa.addInjectable( injectable, new SpringInjectable() {

                @Override
                public Object getInjectableValue( Annotation a ) {
                    return springContext.getBean( getBeanName( injectable, springContext ) );
                }
                
            });
            
        }
    }

After this rather heavy setup phase you can start to inject your spring beans using the @SpringBean annotation:


public class SomeResource {

    private @SpringBean SomeService _service;

    ...

}

Fairly easy, isn’t it? Just define an annotation and define how to resolve beans to that - really straightforward!

Of course, you’re right, the shortcoming here is that you must define (know) which spring beans shall be provided to your resources - consider this to be a security feature ;)

Finally, it was playing around, looking here and there, exploring, and finding out how easy things are - really nice!

And not to forget - jersey 0.6 was released today, as you may also read here.

Now I’m going back to jersey,
cheers,
Martin

Powered by WordPress