JAX-RS and CDI using Resteasy and Weld on Tomcat 7

Create a basic Maven project called RestTest with no archetype in Eclipse. Add the dynamic web project facet to your project and let Eclipse generate a default web.xml file for you. Add the file beans.xml to your project/txp:permlink. Then add the following Weld and Resteasy dependencies to your pom.xml:

<!-- CDI -->
<dependency>
  <groupId>org.jboss.weld.servlet</groupId>
  <artifactId>weld-servlet</artifactId>
  <version>1.1.10.Final</version>
</dependency>
<!-- JAX-RS -->
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-jaxrs</artifactId>
  <version>2.3.5.Final</version>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-jaxb-provider</artifactId>
  <version>2.3.5.Final</version>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-jettison-provider</artifactId>
  <version>2.3.5.Final</version>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-cdi</artifactId>
  <version>2.3.5.Final</version>
</dependency>

Add the following to your web.xml:

<!-- Resteasy -->
<servlet>
  <servlet-name>RestServlet</servlet-name>
  <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<context-param>
  <param-name>resteasy.servlet.mapping.prefix</param-name>
  <param-value>/rest</param-value>
</context-param>
<context-param>
  <param-name>resteasy.scan</param-name>
  <param-value>true</param-value>
</context-param>
<servlet-mapping>
  <servlet-name>RestServlet</servlet-name>
  <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Weld -->
<listener>
  <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
<resource-env-ref>
  <resource-env-ref-name>BeanManager</resource-env-ref-name>
  <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
</resource-env-ref>
<context-param>
  <param-name>resteasy.injector.factory</param-name>
  <param-value>org.jboss.resteasy.cdi.CdiInjectorFactory</param-value>
</context-param>

Now lets create a very basic JAX-RS service:

package com.rest.test;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/")
public class CatService {
  @Inject
  Dog dog;
  @Path("cats")
  @GET
  @Produces("application/json; charset=UTF-8")
  public List<Cat> getCats() {
    dog.bark();
    final List<Cat> cats = new ArrayList<Cat>();
    cats.add(new Cat("Julien", 2));
    cats.add(new Cat("Tom", 6));
    return cats;
  }
}

A small model class:

package com.rest.test;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Cat {
  public String name;
  public int age;
  public Cat() {
    // Resteasy demands a no-arg constructor
  }
  public Cat(final String name, final int age) {
    this.name = name;
    this.age = age;
  }
}

And a small CDI bean that we can inject into our JAX-RS service:

package com.rest.test;
import javax.inject.Named;
@Named
public class Dog {
  public void bark() {
    System.out.println("Meow.");
  }
}

Publish to Tomcat and start the server. On startup you should see something like this in your console:

INFO: Adding scanned resource: com.rest.test.CatService

Resteasy automatically picked up your service. Try it yourself and call the following URL in your browser: http://localhost:8080/RestTest/rest/cats. You should get the following:

[{"cat":{"name":"Julien","age":2}},{"cat":{"name":"Tom","age":6}}]

And of course, if CDI works, you should see this in your console:

Meow.

There you go.