code up

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Jersey(2.0-m12-1)をTomcatで動かす

まずはHello Worldまでを試した。Jersey 2.0についてはドキュメントが未だ整っていないのでJerseyのMavenリポジトリにあるサンプルを参考にしながら作成した。

  • Windows 7 Pro
  • Tomcat 7.0.33
  • Java 7 u11
  • Jersey 2.0-m12-1

といった環境です。

まずはライブラリをインストール。既存の開発環境にJerseyを追加した為、下記の設定は差分で追加したもののみ。また依存性についてはツール(今回の場合はivy)には任せず手動(transitive="false")で行っているため、下記指定は、目的によっては冗長、あるいは不足だったりするかもです。例えばアノテーションによる自動探査を有効にするにはosgi-resource-locatorも必要だったり(結局追加。例外発生時に必要っぽいため)、XML関連のAPI(stax, jaxb)も取り込んでいません。

ivy.xml

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">

	<dependencies defaultconfmapping="runtime->default,sources,javadoc">

		<!-- JAX-RS -->
		<dependency org="com.google.guava" name="guava" rev="${com.google.guava.guava}" transitive="false" />
		<dependency org="org.glassfish.jersey" name="jax-rs-ri" rev="${org.glassfish.jersey}" transitive="false" />
		<dependency org="org.glassfish.hk2" name="hk2-api" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="org.glassfish.hk2" name="hk2-locator" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="org.glassfish.hk2" name="hk2-utils" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="org.glassfish.hk2.external" name="javax.inject" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="org.glassfish.hk2.external" name="cglib" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="org.glassfish.hk2.external" name="asm-all-repackaged" rev="${org.glassfish.hk2}" transitive="false" />
		<dependency org="javax.annotation" name="javax.annotation-api" rev="${javax.annotation.javax.annotation-api}" transitive="false" />
		<dependency org="javax.validation" name="validation-api" rev="${javax.validation.validation-api}" transitive="false" />

		<!-- 例外発生時のメッセージローカライゼーションで内部的に使用している模様 -->
		<dependency org="org.glassfish.hk2" name="osgi-resource-locator" rev="${org.glassfish.hk2.osgi-resource-locator}" transitive="false" />
		<dependency org="org.osgi" name="org.osgi.core" rev="${org.osgi.org.osgi.core}" transitive="false" />

	</dependencies>

</ivy-module>

dependency.properties (上記ivy.xmlに読み込ませているプロパティファイル)

org.glassfish.jersey=2.0-m12-1
com.google.guava.guava=14.0-rc3
org.glassfish.hk2=2.1.60
javax.annotation.javax.annotation-api=1.2-b03
javax.validation.validation-api=1.1.0.Beta4

ここでひとつ問題が出た。アノテーションの自動探査を使いたかったのだが、下記の例外が出てうまく行かなかった。JIRAにレポート(Autodiscovery of providers does not work)が上がっているので不具合なのかもしれない(し、私のやり方が間違っているのかも)。

WARNING: A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by @Consumes and @Produces annotations at Java methods public synchronized javax.ws.rs.core.Response org.glassfish.jersey.server.wadl.internal.WadlResource.getWadl(javax.ws.rs.core.UriInfo) and public synchronized javax.ws.rs.core.Response org.glassfish.jersey.server.wadl.internal.WadlResource.getWadl(javax.ws.rs.core.UriInfo) at matching regular expression /application\.wadl. These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.
WARNING: A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by @Consumes and @Produces annotations at Java methods public synchronized javax.ws.rs.core.Response org.glassfish.jersey.server.wadl.internal.WadlResource.geExternalGrammar(javax.ws.rs.core.UriInfo,java.lang.String) and public synchronized javax.ws.rs.core.Response org.glassfish.jersey.server.wadl.internal.WadlResource.geExternalGrammar(javax.ws.rs.core.UriInfo,java.lang.String) at matching regular expression /([^/]+?). These two methods produces and consumes exactly the same mime-types and therefore their invocation as a resource methods will always fail.

どちらにせよApplicationはひとつしかデプロイしない予定なので、素直にweb.xmlに記載することにする。

まずはアプリケーション(Application)の作成。JAX-RS 2.0によると、Applicationというのは、

A JAX-RS application consists of one or more resources (see Chapter 3) and zero or more providers (see Chapter 4).
JAX-RSアプリケーションはひとつ以上のリソースとゼロ以上のプロバイダから成る。

ということです。RESTリソースを作成するためにはリソースをApplicationに含めなきゃいけないということでしょう。

myapp/r/HelloWorldResource.java (RESTリソース)

package myapp.r;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("helloworld")
public class HelloWorldResource {

	@GET
	@Produces("text/plain")
	public String getHello() {
		return "Hello World!";
	}
}

myapp/r/MyRESTApplication.java (Applicationクラス)

package myapp.r;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/resources/")
public class MyRESTApplication extends Application {

	@Override
	public Set<Class<?>> getClasses() {
		final Set<Class<?>> classes = new HashSet<Class<?>>();
		// register root resource
		classes.add(HelloWorldResource.class);
		return classes;
	}

}

尚、@ApplicationPathの部分は後でweb.xmlでも指定するので(今回のやり方では)省略可能。

そして、このクラスをweb.xmlで指定。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="myapp" metadata-complete="false" version="3.0">
	
	<servlet>
		<servlet-name>MyRESTApplication</servlet-name>
		<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
		<init-param>
			<param-name>javax.ws.rs.Application</param-name>
			<param-value>myapp.r.MyRESTApplication</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>MyRESTApplication</servlet-name>
		<url-pattern>/resources/*</url-pattern>
	</servlet-mapping>

</web-app>

これらをwarに固めて(例: myapp.war)デプロイする。ブラウザでhttp://localhost:8080/myapp/resources/helloworldにアクセスして"Hello World!"と出てくれば成功!

関連記事
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。