May 20, 2009

Create a simple RESTful Webservice with Jersey and Spring

« Simple XML Serialization - Simple Framework | Main | Spring MVC - Example »
I had to combine several sources to find a working solution, mainly http://blogs.sun.com/japod/entry/building_simple_jersey_web_app, http://www.javakaffee.de/blog/2008/04/21/jersey-spring-integration-mostly-complete/, http://n2.nabble.com/The-ResourceConfig-instance-does-not-contain-any-root-resource-classes.-td1519918.html and http://www.jgeppert.com/2009/03/restful-web-services-jax-rs-mit-jersey/ (this one is German). To save the next poor soul some time, I'm writing my findings down.

1. Maven Dependencies

The dependencies I got it to work with are as follows:

        
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.1.9</version>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>2.5.6</version>
        </dependency>

Don't forget to add the Sun Repo to your POM:

  
       <repositories>
         <repository>
            <id>java.net</id>
            <url>http://download.java.net/maven/2</url>
        </repository>
    </repositories>

2. web.xml entries

The greatest difficulty was to find out the right package name, for this has been changed from ...rest.ws... to ...jersey... at some stage which one tends to oversee and wonders, why a ClassNotFoundException is thrown (Murphys law: the first example that you'll find will use the old package). So this is a working example that should be copy-and-paste save (as long as you name your packages after me :o)

    <servlet>
      <servlet-name>Jersey Spring</servlet-name>
      <!--servlet-class>com.sun.ws.rest.spring.SpringServlet</servlet-class-->
      <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
      <init-param>
        <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
        <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
      </init-param>
      <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>de.gisbertamm.frontend</param-value>
      </init-param>
      </servlet>
    <servlet-mapping>
      <servlet-name>Jersey Spring</servlet-name>
      <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

Mind the commented line. This is the obsolete package structure that doesn't work.

3. Define your Spring beans as usual

Nothing special to say about this. Looks like everyday business:

<bean id="dataMapper" class="de.gisbertamm.backend.DataMapper">
    </bean>

4. Inject your beans into your resources

Now everything is fine. Note that not even a setter is needed to inject the dataMapper bean into the resource. Just an @Inject annotation at the field declaration is enough (line 20). Yes, it's that simple. HelloWorldResorce.java

   1:package de.gisbertamm.frontend;
   2:
   3:import com.sun.jersey.spi.inject.Inject;
   4:import de.gisbertamm.backend.IDataMapper;
   5:import de.gisbertamm.daos.ISimpleDao;
   6:import de.gisbertamm.daos.SimpleDao;
   7:import java.util.logging.Logger;
   8:import javax.ws.rs.GET;
   9:import javax.ws.rs.PUT;
  10:import javax.ws.rs.Path;
  11:import javax.ws.rs.Produces;
  12:
  13:/**
  14: * Hello world!
  15: */
  16:@Path("/helloworld")
  17:public class HelloWorldResource {
  18:
  19:    private final Logger LOGGER = Logger.getLogger(HelloWorldResource.class.getName());
  20:    @Inject
  21:    private IDataMapper dataMapper;
  22:
  23:    @GET
  24:    @Produces("text/plain")
  25:    public String getSomeMessage() {
  26:        return this.dataMapper.retrieveData().getValue();
  27:    }
  28:
  29:    @PUT
  30:    public void setNewText(String newText) {
  31:        LOGGER.info("Setting new text value |" + newText + "|");
  32:        ISimpleDao dao = new SimpleDao();
  33:        dao.setValue(newText);
  34:        this.dataMapper.saveData(dao);
  35:    }
  36:}

5. Try it out

For GET- or POST-Requests you can simply use your favourite webbrowser. If you want do do some more fancy things using PUT or DELETE, I'd recomment Googles rest client. However, you've probably known this all before :o)

Technorati Tags:

Posted by gisbert.amm at 8:56 PM in Spring

 

« May »
SunMonTueWedThuFriSat
     12
3456789
10111213141516
17181920212223
24252627282930
31