Jerseyを使用してTomcat6(JavaEE5)でRESTFullサービスを作成する


# Jerseyとは

JavaでRESTFull WEBサービスを提供する仕様である「JAX-RS」のリファレンス実装。読み方は、恐らく「ジャージー」。

# 環境

- Tomcat 6.0
- Jersey 2.5

# Jerseyのインストール

Mavenを使用する場合は、以下を指定。
複数のライブラリが存在するが、サーバ側の実装の場合は下記３つで足りるはず。

```xml
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.17.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-servlet</artifactId>
   	<version>1.17.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.17.1</version>
</dependency>
```

Mavenを使用しない場合は、ここからダウンロードする。
https://jersey.java.net/download.html

# サンプルプログラム

## リソースクラス作成

専用のアノテーションを付与した、POJOクラスを作成。

```java
package jp.co.sample;

@Path("/sample")
public class SampleResource {

	@GET
	public String hello() {
		return "Hello";
	}
}
```

@Pathを付与すると、リソースとして扱われる。また、このリソースを提供するURIを指定する。
@GETを付与すると、GETメソッドに対してレスポンスを返す。

## web.xmlにjerseyサーブレットを登録する

init-paramにリソースクラスのパッケージを指定する。
url-patternがリソースクラスへアクセスするためのルートパスとなる。

```xml
<servlet>
    <servlet-name>Jersey Servlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>jp.co.sample</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Jersey Servlet</servlet-name>
  <url-pattern>/resource/*</url-pattern>
</servlet-mapping>
```

## サービスの参照

下記URLへアクセスすると、「Hello」が返される。

http://localhost:8080/app/resource/sample

* app = コンテキストパス

# 一つのクラスで複数のサービスを提供する

一つのリソースクラスに複数のpublicメソッドがある場合は、メソッドに@Pathを付与する。
( @Pathが付与されていないメソッドが複数あると、アプリケーションサーバ起動時にエラーとなる。)

```java
@Path("/sample")
public class HelloResource {

	@GET
	public String hello() {
		return "Hello!";
	}

	@GET
	@Path("/hello2")
	public String hello2() {
		return "Hello2";
	}

```

“/app/resource/sample" へアクセスすると、helloメソッドが呼ばれる。
“/app/resource/sample/hello2" へアクセスると、hello2メソッドが呼ばれる。

# パラメータを受け取る

## URLでパラメータを渡す

@Pathに{引数名}を指定し、メソッド引数に@PathParamを付与する。

```java
@Path("/sample")
public class HelloResource {

	@GET
	@Path("/hello2/{param}")
	public String hello2(@PathParam("param") String param) {
		return "Hello2 " + param;
	}
```

“/app/resource/sample/hello2/ABC"へアクセスすると、「Hello2 ABC」が返される。

## クエリストリングでパラメータを渡す

メソッド引数にQueryParamを付与する。

```java
@Path("/sample")
public class HelloResource {

	@GET
	@Path("/hello3")
	public String hello3(@QueryParam("param") String param) {
		return "Hello3 " + param;
	}
```

“/app/resource/sample/hello3?param=ABC"へアクセスすると、「Hello3 ABC」が返される。

## パラメータをオブジェクトでやりとりする

パラメータを保持するクラスに、@InjectParamを付与する。

```java
@Path("/sample")
public class HelloResource {
	
	@InjectParam
	private HelloParamDto dto;

	@GET
	@Path("/hello4")
	public String hello4() {
		return "Hello4 " + dto.name;
	}
```

パラメータを保持するクラスは、POJOで作成しフィールドに@QueryParamを付与する。@PathParamは対応していない模様。

```java
public class HelloParamDto {

	@QueryParam("name1")
	public String name1;

	@QueryParam("name2")
	public String name2;
}
```

# 結果をJSONで返す

@ProducesでレスポンスのタイプをJSONに指定すると、戻り値をJSON形式に変換してくれる。

```java
@Path("/sample")
public class HelloResource {
	
	@GET
	@Path("/helloJson")
	@Produces(MediaType.APPLICATION_JSON)
	public HelloResultDto helloJson() {
		HelloResultDto dto = new HelloResultDto();
		dto.name1 ="AAA";
		dto.name2 ="BBB";
		dto.name3 ="CCC";
		dto.name4 ="DDD";
		return dto;
	}
```

戻り値のクラスには、@XmlRootElementを付与する。

```java
@XmlRootElement
public class HelloResultDto {

	public String name1;
	public String name2;
	public String name3;
	public String name4;
}
```

「/app/resource/sample/helloJson」へアクセスると下記結果が返される。

```
{“name1":"AAA","name2":"BBB","name3":"CCC,"name4":"DDD"}
```