はじめに
CDIを利用したJAX-RS 2.0のアプリを作成し、Tomcat 8で実行するサンプル。
web.xmlレスの情報が少ないので、まとめておく。
ビルドにはJDK 8とMaven 3を利用。
また、JAX-RS 2.0の実装としてJerseyを、CDIの実装としてWeldを利用。
実行にはServlet 3.0に対応したTomcat 7以降(ここで試したのはTomcat 8)が必要。
.
|-- pom.xml
`-- src
`-- main
|-- java
| `-- redj
| `-- hello
| `-- cdi
| `-- jersey
| |-- ApplicationConfig.java
| |-- Greeting.java
| `-- GreetingResource.java
`-- resources
`-- META-INF
`-- beans.xml
ソース
xml version="1.0" encoding="UTF-8"
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlnsxsi="http://www.w3.org/2001/XMLSchema-instance" xsischemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>redj</groupId>
<artifactId>hello-cdi-jersey</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<projectbuildsourceEncoding>UTF-8</projectbuildsourceEncoding>
<mavencompilersource>1.8</mavencompilersource>
<mavencompilertarget>1.8</mavencompilertarget>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-core</artifactId>
<version>2.3.2.Final</version>
</dependency>
</dependencies>
</project>
weld-servlet-coreには、WebコンテナでCDIを実現するServletが含まれている。
jersey-cdi1xは、Jersey内のCDIの実装をHK2からCDIに切り替える。
src/main/java/redj/hello/cdi/jersey/Greeting.java
package redj.hello.cdi.jersey;
import javax.enterprise.context.RequestScoped;
@RequestScoped
public class Greeting {
public String sayHello(String name) {
return "hello," + name + "!";
}
}
src/main/java/redj/hello/cdi/jersey/GreetingResource.java
package redj.hello.cdi.jersey;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("greeting/{name}")
public class GreetingResource {
@Inject
private Greeting greeting;
@GET
@Produces("text/plain")
public String sayHello(@PathParam("name") String name) {
return greeting.sayHello(name);
}
}
src/main/java/redj/hello/cdi/jersey/ApplicationConfig.java
package redj.hello.cdi.jersey;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("hello-cdi-jersey")
public class ApplicationConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(GreetingResource.class);
return classes;
}
}
src/main/resources/META-INF/beans.xml
xml version="1.0" encoding="UTF-8"
<beans/>
weld-servlet-coreでCDIを有効化している場合、Managed Beanを全てアノテーションで定義していたとしても空のbeans.xmlが必要になる。
https://docs.jboss.org/weld/reference/latest/en-US/html/environments.html
In general, an implicit bean archive does not have to contain a beans.xml descriptor. However, such a bean archive is not supported by Weld Servlet, i.e. it’s excluded from discovery.
ビルド
$ mvn clean install
デプロイ
$ cp target/hello-cdi-jersey-1.0-SNAPSHOT.war $CATALINA_HOME/webapps/
実行
$ curl http://localhost:8080/hello-cdi-jersey-1.0-SNAPSHOT/hello-cdi-jersey/greeting/world
hello,world!
参考