はじめに
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
ソース
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <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!