ぺーぺーSEのブログ

備忘録・メモ用サイト。

Jersey、JSONでHello World

Mavenでサンプルプロジェクトを作成する。

mvn archetype:generate
 -DgroupId=org.sample
 -DartifactId=JerseyHelloWorld
 -Dversion=1.0.0
 -DarchetypeArtifactId=maven-archetype-webapp

POMを下記のように作成。

<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>org.sample</groupId>
  <artifactId>JerseyHelloWorld</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>

  <properties>

    <!-- Generic properties -->
    <jdk.version>1.7</jdk.version>
    <encoding>UTF-8</encoding>

    <!-- Jersey -->
    <jersey.version>1.17.1</jersey.version>

  </properties>

  <build>
    <finalName>JerseyHelloWorld</finalName>
    <plugins>
      <!-- compiler -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>${jdk.version}</source>
          <target>${jdk.version}</target>
          <encoding>${encoding}</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>

    <!-- Jersey -->
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>${jersey.version}</version>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-servlet</artifactId>
      <version>${jersey.version}</version>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-json</artifactId>
      <version>${jersey.version}</version>
    </dependency>

  </dependencies>
</project>

JSON対応したオブジェクトクラスを作成する。

■オブジェクトクラス(org.sample.bean.Person)

package org.sample.bean;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {
	private Integer id;
	private String name;
	private String address;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}
}

JSONを扱うリソースクラスを作成。

■リソースクラス(org.sample.resource.PersonResource)

package org.sample.resource;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.sample.bean.Person;

import com.sun.jersey.api.NotFoundException;

@Path("/person")
public class PersonResource {

	private static List<Person> persons = null;
	static {
		persons = new ArrayList<>();
		persons.add(createPerson(1, "suzuki", "Tokyo"));
		persons.add(createPerson(2, "satou", "Osaka"));
		persons.add(createPerson(3, "tanaka", "Naogya"));
	}

	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public List<Person> getPersons() {
		return persons;
	}

	@Path("{id}")
	@GET
	@Produces({ MediaType.APPLICATION_JSON })
	public Person getperson(@PathParam("id") Integer id) {
		if (id > persons.size()) {
			throw new NotFoundException("No such person.");
		}
		return persons.get(id - 1);
	}

	@PUT
	@Consumes({ MediaType.APPLICATION_JSON })
	public Response putPerson(Person input) {
		persons.add(input);
		return Response.ok().build();
	}

	@DELETE
	@Consumes({ MediaType.APPLICATION_JSON })
	public Response deletePerson(Person input) {
		Integer id = input.getId();
		if(id != null){
			for(int i=0; i<persons.size(); i++) {
				Person person = persons.get(i);
				if(id.equals(person.getId())){
					persons.remove(i);
					return Response.ok().build();
				}
			}
		}
		
		return Response.status(400).build();
	}

	private static Person createPerson(Integer id, String name, String address) {
		Person person = new Person();
		person.setId(id);
		person.setName(name);
		person.setAddress(address);
		return person;
	}
}

アプリケーションクラス(org.sample.application.SampleApplication)を更新して下記のようにする。

■アプリケーションクラス(org.sample.application.SampleApplication)

package org.sample.application;

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

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

import org.sample.resource.PersonResource;

@ApplicationPath("")
public class SampleApplication extends Application {
	
	@Override
	public Set<Class<?>> getClasses() {
		Set<Class<?>> s = new HashSet<Class<?>>();
		s.add(PersonResource.class);
		return s;
	}

}

■web.xml(JAX-RX非対応のコンテナの場合)

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>org.sample.application.SampleApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>

上記の例はTomcatのようにJAX-RS非対応のコンテナの場合の記述方法。
GlassFishのようにJAX-RS対応のコンテナの場合は下記。
■web.xml(JAX-RX対応のコンテナの場合)

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.sample.application.SampleApplication</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>

また、アプリケーションクラス(org.sample.application.SampleApplication)を使用しなくてもデプロイ対象のリソースクラスをJAX-RSへ教えることができる。
サーブレットの定義に「com.sun.jersey.config.property.packages」パラメタを使用してリソースクラスがあるパッケージを教えてあげる。
■web.xml(JAX-RX非対応のコンテナ、且、アプリケーションクラス使用しない場合)

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>Jersey REST Service</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>org.sample.resource</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>

上記でデプロイが成功すると起動時に下記のようなログが標準出力される。(Tomcat

情報: Root resource classes found:
  class org.sample.resource.PersonResource

プロバイダクラスを見つけた場合は下記のようなログが出力される。

情報: Provider classes found:
  class org.sample.provider.JsonListMapMessageBodyWriter
  class org.sample.provider.JsonMapMessageBodyWriter
  class org.sample.provider.JsonMapMessageBodyReader
  class org.sample.provider.JsonListMapMessageBodyReader

プロバイダクラスについては下記。



以上でサンプル更新完了。
サンプルを起動した後、HTTP GETメソッドで「http://[FQDN]:8080/JerseyHelloWorld/person」へアクセスすると下記のJSONが返る。

{"person":[{"address":"Tokyo","id":"1","name":"suzuki"},{"address":"Osaka","id":"2","name":"satou"},{"address":"Naogya","id":"3","name":"tanaka"}]}

HTTP GETメソッドで「http://[FQDN]:8080/JerseyHelloWorld/person/1」へアクセスすると下記のJSONが返る。idが1のpersonが返る。

{"address":"Tokyo","id":"1","name":"suzuki"}

HTTP PUTメソッド、Content-Typeをapplication/json、さらにボディを下記でアクセスすると

{"address":"Yokohama","id":"4","name":"takahashi"}

上記のJSONに該当するperson情報が登録される。


HTTP DELETEメソッド、Content-Typeをapplication/json、さらにボディを下記でアクセスすると

{"id":"1"}

上記のJSON、idが1に該当するperson情報が削除される。




参考:http://d.hatena.ne.jp/w650/20110119/1295411262