第1回 いまさら始めるJavaでRESTful Webサービス構築
第1回 いまさら始めるJavaでRESTful Webサービス構築
皆さんはRESTful Webサービスを構築した経験はありますか?「いや、まったく・・・」という方や、「バリバリ作ってるよ!」という方、「RESTful?なにそれ?おいしいの?」という方もいると思います。
本連載では、JAX-RS(The Java™ API for RESTful Web Services)を使って、簡単なRESTful Webサービスの構築方法をご紹介していきます。なお対象読者は、Java言語を利用したことがあり、Webアプリケーション開発経験のある方を想定しています。
RESTful? JAX-RS?
冒頭に出てきたRESTfulやJAX-RSという単語、いったいどういうものなのでしょう?
まずRESTfulですが、下記の抜粋(http://ja.wikipedia.org/wiki/RESTから一部抜粋)に登場する「Roy Fielding」氏が提唱するREST原則に従って実装されたものを、RESTfulと言います。
Representational State Transfer(REST) は、ウェブのような分散ハイパーメディアシステムのためのソフトウェアアーキテクチャのスタイルのひとつである。この語は2000年に、HTTPプロトコル規格の主要著者の一人であるRoy Fieldingが、ウェブについて書いた博士論文で初めて現れ、ネットワーキングコミュニティの中ですぐに広く使われることになった。 |
ではRESTはいったいどういうものかというと、前述のURLや、その他RESTに関するドキュメントを参照すると詳細な説明がされていますが、簡単に説明すると以下の通りです。
- HTTPを使ったシンプルなWebサービス
- すべてのリソースは、一意なアドレスで識別される(例えばhttp://example.com/resources/1234という感じ)
- 特定のHTTPメソッドを使用して操作する(GET、POST、PUT、DELETEなど)
- JSON、XML、YAMLがサポートされている
これらの仕様にそって実装されたサービスがRESTful Webサービスと呼ばれます。以下に、簡単な図でRESTful Webサービスにアクセスする流れを紹介します。
図 1 RESTful Webサービス図
上図では、HTTPメソッドのGETを利用してWebサービスにアクセスし、XMLでレスポンスを受け取る例です。RESTful Webサービスは特別な技術を使っているわけでなく、皆さんが普段から利用している技術を利用してサービスを提供しています。したがって、クライアント側はHTTPさえ扱えればなんでも可能と言えます。
RESTful Webサービスについて、なんとなくイメージはつかめたでしょうか?
代表的なRESTful Webサービスを、下記にあげておきます。
- Amazon
Amazonが提供するRESTful API。このAPIを利用して、Amazonが提供する各種Webサービスから情報を取得することができる。 - Yahoo!
Yahoo!が提供するRESTful API。このAPIを利用して、Yahoo!が提供する各種Webサービスから情報を取得することができる。 - mixi
mixiが提供しているRESTful API。このAPIを利用して、ユーザー情報などを取得することができる。 - Twitter
Twitterが提供するRESTful API。このAPIを利用して、TimelineやTweetなどを取得することができる。 - 楽天
楽天が提供するRESTful API。このAPIを利用して、楽天市場内の商品情報を取得することができる。
Fielding氏の論文は、下記のURLで参照可能です(英文)。
次はJAX-RSですが、Java Community Process(JCP)という組織が定めたRESTful Webサービスの実装に関するJavaの仕様のことです。JSR311として定義されており、詳しい仕様は下記の資料をご参照ください。
- JSR 311: JAX-RS: The Java™ API for RESTful Web Services
http://jcp.org/en/jsr/detail?id=311
JAX-RSを使ってみる
では早速・・・といきたいところですが、JAX-RS自体は単なる仕様でしかありません。しかし、各ベンダーからJAX-RSの仕様に則った実装が提供されています。主要な実装は下表のとおりです。
表 1 主要なJAX-RS実装
Apache CXF | The Apache Software Foundationが提供しているJAX-RSの実装。JAX-WSなども含んでいる。 |
Jersey | GlassFish(オープンソース・コミュニティ)が提供しているJAX-RSのリファレンス実装。リファレンス実装とは、JAX-RSの実装を行う上で参考となる実装のこと。 |
RESTEasy | JBossが提供しているJAX-RSの実装。 |
Restlet | Restletが提供しているJAX-RSの実装。 |
インターネット上の様々なメディアやブログなどの紹介記事では、JAX-RSによるRESTful WebサービスはJerseyが使われていることが多いですが、本連載ではApache CXFを使って説明を行いたいと思います。Apache CXFを選択した強い理由はないのですが、筆者が使い慣れているということで選択しました。基本的には、どのベンダーもJSR311に則った実装を提供しているため、本連載の内容を別の実装を使って作成することも可能だと思います。
なお、RESTful Webサービスを構築するにあたり、DIコンテナとしてSpring Framework、O/RマッパーとしてMyBatisを使用します。また、開発環境はEclipse3.6とMaven3.x(Maven2.xでも可)、Java™ SE6を使用します。
以下は、筆者の開発環境です。参考程度に載せておきます。
OS | MacOSX Lion Server |
JDK | 1.6.0_29 |
Maven | 3.0.3 |
Tomcat | 6.0.16 |
Eclipse | 3.6(Eclipse Java EE IDE for Web Developers) |
開発環境の準備
JAX-RSを使ってRESTful Webサービスを作るにあたり、まずはEclipse用のWebアプリケーションプロジェクトを作成しましょう。
Mavenを使って、コマンドプロンプトやコンソールから、Eclipseプロジェクトを作成します。MavenコマンドにはPathを通しておいてください。
$ mvn archetype:generate |
筆者は、下記の値を指定してプロジェクトを作成しました。
- Choose a number or apply filter: org.apache.maven.archetypes:maven-archetype-webappの番号
- Choose version: 1.0
- groupId: jp.example.webapp
- artifactId: jax-rs
- version: 1.0-SNAPSHOT
- package: jp.example.webapp
そうすると、jax-rsというプロジェクトが作成されます。次は、今作成したプロジェクトをEclipseで認識できるようにします。
$ cd jax-rs $ mvn eclipse:eclipse |
これでプロジェクトの作成は終わりです。Eclipseでインポートしておきましょう(Mavenで作成したプロジェクトをEclipseにインポートするときは、m2eclipse pluginを使ってください)。
プロジェクトの設定
新しく作成したプロジェクトで開発を進めていく上で、いくつかの設定をする必要があります。
ソースフォルダの追加
プロジェクトのプロパティを開き、「Java Build Path」を選択します。
図 2 Java Build Path
Sourceタブを開き、「Add Folder…」をクリックします。開いたダイアログで「Create New Folder…」をクリックし、Folder nameに「src/main/java」と入力してFinishボタンをクリックします。
図 3 フォルダを追加したところ
上図の通りに作成されたらOKをクリックしてダイアログを閉じます。そのままプロパティダイアログもOKをクリックして閉じます。
ファセットの設定
次は、プロジェクトのファセットを設定します。プロジェクトのプロパティを開き、Project Facetsを選択します。
図 4 Project Facets
Dynamic Web Moduleにチェックをつけます。Versionは2.5を選択して下さい。上図では表示されていませんが、初回のファセット設定では、下の方に「Further configuration available…」というリンクがでるので、そこをクリックしてダイアログを開き、Generate web.xml deployment descriptorのチェックを外してOKをクリックしてください。
ここでいったんOKをクリックしてプロパティを閉じます。そして再度プロパティを開き、Deployment Assemblyを選択します。WebContentを削除して、あらたにsrc/main/webappフォルダの追加と、Maven Dependenciesを追加してください。
図 5 Deployment Assembly
WebContentフォルダは削除して構いません。
Maven Dependencyの設定
次は、Maven Dependencyの設定を行なって、開発に必要なライブラリを登録します。pom.xmlファイルを開いて、下記の設定を行なってください。
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jp.example.webapp</groupId> <artifactId>jax-rs</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>jax-rs Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>2.5.1</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-bundle-jaxrs</artifactId> <version>2.5.1</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.0.6.RELEASE</version> <type>jar</type> <scope>compile</scope> </dependency> </dependencies> <build> <finalName>jax-rs</finalName> </build> </project> |
web.xmlの設定
次に、web.xmlの設定を行います。src/main/webapp/WEB-INF/web.xmlを開いてください。なお、今回はServlet2.5を使用するため、デフォルトで記述されているDTDは使用せず、代わりにXML Schemaを使用します。最後に、web.xmlの全体を掲載しますので、参考にしてください。
まずは、アプリケーション起動時にSpring FrameworkのApplicationContextを生成できるように、Listenerの定義を行います。以下の設定を記述してください。
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> |
そして、Bean定義ファイルのパスをcontext-paramタグを使って定義します。以下の設定を記述してください。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/applicationContext.xml </param-value> </context-param> |
最後に、Servletの定義を行います。Servletは、Apache CXFが提供しているServletを使用します。以下の設定を記述してください。
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> |
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: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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Archetype Created Web Application</display-name> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> |
Bean定義ファイルの設定
最後にBean定義ファイルを作成します。src/main/webapp/WEB-INFの下にspringフォルダを作成し、そこにapplicationContext.xmlを作成してください。
作成したファイルに、以下の設定を記述してください。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml" /> <context:component-scan base-package="jp.sample.jaxrs" /> </beans> |
これでプロジェクトの設定は終わりです。WTPとTomcatを使って、作成したプロジェクトを起動してみてください。起動後、http://localhost:8080/jax-rs/にアクセスすると、HTTP Status 200とともに「No services have been found.」が返ってきます。まだなにもサービスを登録していないため、この結果は正常です。
WTPは、Eclipse Java EE IDE for Web Developersであればインストールされていますが、これ以外のEclipseである場合は、別途WTPプラグインをインストールしてください。
Hello World
最後に、おなじみのHello Worldを表示する機能を実装してみましょう。まずは、SampleResource.javaとHelloResource.javaを作成します。それぞれのファイルに記述するコードは、下記を参照してください。
package jp.sample.jaxrs.service; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @Path("/sample") public interface SampleResource { @GET @Path("/hello/{message}") String sayHello(@PathParam("message") String message); } |
package jp.sample.jaxrs.service; import org.springframework.stereotype.Component; @Component public class HelloResource implements SampleResource { /** * {@inheritDoc} */ @Override public String sayHello(String message) { return String.format("Hello, %s", message); } } |
次は、先ほど作ったクラスをWebサービスとして定義するため、applicationContext.xmlに以下の設定を追加します。
<jaxrs:server id="jaxrsservice" address="/"> <jaxrs:serviceBeans> <ref bean="helloResource" /> </jaxrs:serviceBeans> </jaxrs:server> |
WTPとTomcatを使ってプロジェクトを起動し、http://localhost:8080/jax-rs/sample/hello/123にアクセスしてみてください。「Hello, 123」と返ってくれば成功です。
おわりに
第一回はいかがだったでしょうか。RESTfulやJAX-RS、環境構築手順やプロジェクト作成方法について、駆け足で説明してきました。RESTを利用したWebサービスを公開すれば、言語やアーキテクチャを選ばず、いろいろなアプリケーションと連携を取ることができます。
次回は、作成したプロジェクトを利用して、今回のサンプルでは触れなかったその他のHTTP Methodについて説明していきます。また、今後の連載の予定として、データベース連携を追加してデータの参照や更新を行う機能の実装について説明いたします。お楽しみに!
第1回 おしまい
※.記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。