...

WAS Feature Pack for Web 2.0 JAX-RS -

by user

on
Category: Documents
61

views

Report

Comments

Transcript

WAS Feature Pack for Web 2.0 JAX-RS -
WAS Feature Pack for Web 2.0 による
JAX-RS
アプリケーション開発ガイド
-1-
1 概要 .......................................................................................................................................... 4
1-1 Feature Pack for Web 2.0 とは ........................................................................................ 4
1-2 Web 2.0 FP 1.0.1 の新機能................................................................................................ 5
2 RESTful Web サービス設計................................................................................................... 7
2-1 REST/ROA の概要 .............................................................................................................. 7
2-1-1 REST とは.......................................................................................................................... 7
2-1-2 ROA とは............................................................................................................................ 7
2-2 ROA による設計の手順 ....................................................................................................... 8
2-2-1 リソースの設計.................................................................................................................. 8
2-2-2 オペレーションの設計 ....................................................................................................... 8
2-2-3 表現の概要設計 ............................................................................................................... 8
2-2-4 表現の詳細設計 ............................................................................................................... 9
2-2-5 設計の注意事項 ............................................................................................................. 10
3 Web 2.0 FP の適用 ............................................................................................................... 11
3-1 WAS ランタイムへの Web 2.0 FP の適用........................................................................ 11
3-2 開発環境の設定 ................................................................................................................. 15
4 JAX-RS プロバイダーの開発 ................................................................................................ 19
4-1 JAX-RS 概要 ...................................................................................................................... 19
4-2 簡単な JAX-RS アプリケーションの開発.......................................................................... 20
4-2-1 Web プロジェクトの作成 .................................................................................................. 21
4-2-2 リソース・クラス、リソース・メソッドの作成...................................................................... 23
4-2-3 JAX-RS Application クラスのサブクラスの作成 ........................................................... 24
4-2-4 稼動確認 ......................................................................................................................... 25
4-3 JAX-RS アプリケーションの開発 ....................................................................................... 26
4-3-1 リソース・クラス、リソース・メソッドの指定...................................................................... 26
4-3-2 エンティティー・ボディーの取得/生成 ............................................................................. 30
4-3-3 HTTP リクエスト情報の取得 ........................................................................................... 41
4-3-4 レスポンス HTTP ヘッダーの設定 ................................................................................. 45
5 RESTful Web サービス・クライアントの開発 ....................................................................... 48
5-1 Dojo Toolkit による HTTP 送信 ....................................................................................... 48
5-1-1 dojo.xhr ............................................................................................................................ 48
5-1-2 dojo.data.ItemFileReadStore........................................................................................ 49
5-1-3 dojo.xhr と DataStore の連携 ........................................................................................ 50
-2-
5-2 Java による HTTP 送信 ..................................................................................................... 51
5-2-1 java.net.URL ................................................................................................................... 51
5-2-2 Apache HttpClient .......................................................................................................... 54
5-2-3 Apache Wink ................................................................................................................... 56
参考資料..................................................................................................................................... 60
-3-
1 概要
本章では、Feature Pack for Web 2.0 V1.0.1 の概要について、説明します。
1-1 Feature Pack for Web 2.0 とは
Feature Pack for Web 2.0 (以降、Web 2.0 FP) は、WebSphere Application Server (以降、WAS) にオ
プションでインストール可能な製品拡張で、WAS 上で稼働する Web アプリケーションを使いやすくする
ための新機能を付加的に提供します。Web 2.0 FP は、WAS のライセンスをお持ちであれば、無償で利
用できます。
Web 2.0 FP V1.0.1 によって追加される機能は、以下の通りです。
•
•
•
•
IBM JAX-RS
Java API for RESTful Web Services (JAX-RS) は、REST (Representational State
Transfer) に準拠するサービスを開発するためのメカニズムを提供するプログラミング・モ
デルです。JAX-RS は Java EE 6 に含まれるプログラミング・モデルです。Web 2.0 FP を
使用することで、Java EE 5、J2EE 1.4 をベースとしている WAS V7、WAS V6.1 において
先行して JAX-RS のプログラミング・モデルを使用することが可能になります(WAS V6.0
では、JAX-RS の機能を使用することはできません)。JAX-RS を使用すると、RESTful
Web サービスの開発が簡素化されます。これらの詳細は4章で説明します。Web 2.0 FP
V1.0.1 で提供される JAX-RS のバージョンは 1.0 です。
Ajax プロキシー・ランタイム
Ajax プロキシーは、HTTP のリバース・プロキシーの機能を提供します。Ajax プロキシー
は、オプションの Web アーカイブ・ファイル(WAR)として配布され、アプリケーションに直接
インストールすることも、既存のアプリケーション・エンタープライズ・アーカイブ(EAR)ファイ
ルと結合することもできます。プロキシーを使用すると、Ajax を使用する際に、複数ドメイ
ンへのクライアント要求を仲介することができます。JavaScript では、セキュリティー制約
により、JavaScript の生成元でないサーバーに対するネットワーク要求は開始できませ
ん。このポリシーは、ほとんどの主要ブラウザーで same-origin ポリシーと呼ばれていま
す。Ajax プロキシーによって、JavaScript の same-origin ポリシーの問題を解決すること
ができます。
JSON4J ライブラリー
JSON(JavaScript Object Notation)は、JavaScript との親和性の高いデータ・フォーマ
ットの一種です。このライブラリーを使うことで、Java を利用した、List や Map 形式のオブ
ジェクトと JSON データ・フォーマット形式の相互変換を容易に行うことができます。また、
XML を表す Java オブジェクトから JSON データ・フォーマット形式への変換を行なうことも
できます。
Ajax クライアント・ランタイム
IBM によって拡張された Dojo Toolkit と、Eclipse プラグインが含まれます。Dojo Toolkit
-4-
は、リッチな画面コンポーネントを提供し、ブラウザーの差異を吸収する JavaScript ライブ
ラリーです。
IBM Atom ライブラリー
IBM による Dojo Toolkit の拡張です。JavaScript によって、Atom 形式のデータを処
理することが可能です(dojox.atom プロジェクトに提供されたため、現在では非推奨で
す)。
http://docs.dojocampus.org/dojox/atom
IBM SOAP ライブラリー
IBM による Dojo Toolkit の拡張です。JavaScript によって、SOAP 形式のプロトコルを
送信することが可能になります。
IBM OpenSearch ライブラリー
IBM による Dojo Toolkit の拡張です。JavaScript によって、OpenSearch サービスに
対して検索処理を実行することが可能です(dojox.data.OpenSearchStore プロジェクト
に提供されたため、現在では非推奨です)。
http://docs.dojocampus.org/dojox/data/OpenSearchStore
IBM ゲージ・ウィジェット
IBM による Dojo Toolkit の拡張です。JavaScript によって、ゲージ・ウィジェット(操作
可能なグラフオブジェクト)を作成することが可能です(dojox.widget.AnalogGauge プロ
ジェクトおよび dojox.widget.BarGauge プロジェクトに提供されたため、現在では非推
奨です)。
http://docs.dojocampus.org/dojox/widget/AnalogGauge
http://docs.dojocampus.org/dojox/widget/BarGauge
•
RPC アダプター・ライブラリー
JavaBeans に対する、RPC 形式の HTTP インターフェースを作成するためのライブラリ
ーです。これによって、既存の JavaBeans を HTTP によってリモート呼び出しすることが可
能になります。
•
Feed ライブラリー
フィードを生成するためのライブラリーです。Java によって、Atom と RSS を処理するこ
とが可能になります(RSS は読取のみ)。
•
Web メッセージング・サービス
Publish/Subscribe 型のメッセージングを実現するための機能です。Comet サーバーモ
デルを実装するための、Java による Bayeux プロトコルを処理するライブラリーが提供さ
れます(クライアント側は、Dojo Toolkit の標準機能によって提供されています)。
1-2 Web 2.0 FP 1.0.1 の新機能
Web 2.0 FP V1.0.1 は、V1.0.0 と比較して、以下のような様々な新しい機能が追加・変更されていま
す。
•
•
JAX-RS
新規に追加されました。4章で説明します。
Ajax クライアント・ランタイム
ベースとなる Dojo Toolkit のバージョンが 1.3 から 1.4 になり、パフォーマンスの向上や、
サポートするブラウザーの追加などが行われています。詳細は、以下の URL を参照してく
ださい。
http://docs.dojocampus.org/releasenotes/1.4
-5-
•
•
•
Ajax プロキシー
proxy-config.xml の mime-type に対するパターン・マッチングがサポートされました。
RPC アダプター
サブクラス変換のサポートを通して、データにアクセスするときの、よりフレキシブルなデ
ータ・タイプのセットへのアクセスがサポートされました。
Web メッセージング・サービス
Dojo 1.3 のデフォルトの Bayeux 通信トランスポートが、新しい JSON トランスポートに変
更されました。
-6-
2 RESTful Web サービス設計
この章では、RESTful Web サービスの設計について説明します。
2-1 REST/ROA の概要
2-1-1 REST とは
REST とは、Representative State Transfer の略で、Roy Fielding が 2000 年に論文として発表した、Web
のアーキテクチャー・スタイルです。原文によれば、REST は、"クライアント-サーバー"、"ステートレス"、"
キャッシュ"、"統一インターフェース"、"階層化システム"、"コードオンデマンド"の 6 つの特徴を兼ね備
えたアーキテクチャー・スタイルであるとされます。そして、これらの特徴を兼ね備えた Web サービスを
RESTful Web サービスと呼びます。
※ REST はアーキテクチャー・スタイルであり、実装を規定していないため、一般には"ful"の接尾語
を付与します。
ただし、これらの特徴を全て守ったものが一般的に REST と呼ばれているわけではなく、現在のとこ
ろ、特に"ステートレスサーバー"と"統一インターフェース"の 2 点が重視されることが多いようです。ま
た、RESTful Web サービスは、"HTTP リクエストによってデータを取得できるサービス"を指すことが多い
ため、以降は、これを広義の RESTful Web サービスとして解説します。
RESTful Web サービスでは、HTTP リクエストによってデータを取得することができるので、HTTP ライ
ブラリーの存在するプログラミング言語であれば、容易に呼び出すことが可能です。特に Web システム
においては、フロントエンドの JavaScript から HTTP リクエストを送信し、それによって HTML 内のデータ
を書き換える、Ajax を生かしたアプリケーションを構築することができますので、RESTful Web サービス
を作成することには大きなメリットがあります。また、この Web 2.0 FP に含まれている Dojo Toolkit には、
RESTful Web サービスとの連携が考慮されているリッチなユーザー・インターフェースが組み込まれたパ
ーツが用意されていますので、RESTful Web サービスを組み合わせることで、よりリッチな、使いやすい
Web ページを、エンドユーザーに提供することが可能になります。
2-1-2 ROA とは
ROA とは、Resource Oriented Architecture、リソース指向アーキテクチャーの略で、REST のスタイル
を実装するに当たって、設計の指針となるアーキテクチャーの 1 つです。REST はアーキテクチャー・ス
タイルであり、実装を規定していないため、どのように実装しても構いません。これは自由度が高いことを
意味していますが、それと引き換えに、独自の実装が溢れる原因となり、結果的に複数の RESTful Web
サービス間の、インターフェースが統一されなくなってしまいます。これを解決するのが、ROA という考え
方です。
ですので、RESTful Web サービスは全て ROA に基づいているということはありません。ROA に基づい
ている RESTful Web サービスの例としては、以下のようなものがありますので、一度ご覧ください。
-7-
•
•
WebSphere CloudBurst REST API
http://publib.boulder.ibm.com/infocenter/wscloudb/v2r0/topic/com.ibm.websphere.clo
udburst.doc/ra/ret_overview.html
IBM Smart Business Development and Test on the IBM Cloud REST API
http://www-180.ibm.com/cloud/enterprise/beta/ram/assetDetail/generalDetails.faces
?guid={AE9C1E74-F8C5-A11C-DDE3-D0E6F12515FE}
2-2 ROA による設計の手順
2-2-1 リソースの設計
ROA では、URI で表現される、"リソース"というものを定義します。リソースは操作する対象を指し示す
もので、名詞になります。例えば、図書館の蔵書を管理するアプリケーションであれば、"本"や"登録さ
れているアカウント"、"カテゴリー"などが、リソースになり得ます。この場合、URI は以下のようになるでし
ょう。
•
•
•
http://<hostname>/books
http://<hostname>/accounts
http://<hostname>/categories
※ 慣習的に、リソースの名称は複数形で書かれます。これは、例えば"アカウント"リソースは複数の"
アカウント"の情報を返すものであることが多いためです。
2-2-2 オペレーションの設計
その次に、HTTP メソッドで表現される、"リソースに対するオペレーション"を定義します。このオペレ
ーションとは、いわゆるデータベースに対する CRUD 処理(新規作成、検索、更新、削除)などを指しま
す。HTTP メソッドと CRUD 処理は、一般に次のようにマッピングされます。
•
•
•
•
HTTP GET
HTTP POST
HTTP PUT
HTTP DELETE
:
:
:
:
検索
新規作成
更新(対象が存在しない場合、新規作成)
削除
上記の例では、http://<hostname>/books に対して、HTTP GET リクエストを送信すると、本の検索がで
き、http://<hostname>/accounts に HTTP POST リクエストを送ると、アカウントの新規作成ができる、という
設計になります。
2-2-3 表現の概要設計
次に、HTTP クエリー・パラメータや HTTP ヘッダーなどで表される、"表現"を定義します。表現とは、
HTTP リクエストに含まれるリソースを絞り込む条件や、HTTP レスポンスに含まれるリソースの状態を表
す HTTP ステータスコードのことを指します。ここで注意すべきなのは、全ての情報を、エンティティー・
ボディーに含まれるメッセージで表現しようとしないことです。HTTP に存在する仕組みを利用せずに、
XML 文書などをエンティティー・ボディーに入れて、全てを表現しようとすることは、ROA において最も
-8-
避けるべき設計の 1 つです。HTTP ステータスコードや HTTP ヘッダーを最大限に利用し、エンティティ
ー・ボディーに入れるメッセージを最小限にすることが望ましい設計です。
リクエストの表現では、リソースをどのように特定するか、また、取得するリソースの形式をどのように指
定するか、という点を考えて設計します。例えば、それぞれの本には ID が振られている場合、ID が 10
番の本は、次のような URI で特定できるように設計します。
•
•
http://<hostname>/books/10
http://<hostname>/books?id=10
一般に、前者のパス変数による指定は、階層構造のあるリソースに適しており、後者のクエリー・パラメ
ータによる指定は、並列にならぶ複数のパラメーターを持つリソースに適しています。リソースの持つ特
性によって、どちらを利用するか、もしくは両方使用する場合、どのように使い分けるか、を考慮する必
要があります。
ここで、ID10 番の本の情報として、本のメタ情報と、表紙の画像イメージファイルを場合によって切り
替えたいこともあると思いますが、この場合は、HTTP ヘッダーの Accept が適切な指定になります。ま
た、メタ情報を記述する言語を日本語、英語で切り替えたいといった場合は、Accept-Language が適切
です。このように、適切な HTTP ヘッダーやパラメーターを利用することが望ましい設計です。どうしても
既存の HTTP ヘッダーでは表現できない場合には、独自の HTTP ヘッダーやパラメーターを用いて切り
替えることも考慮に入れます。
レスポンスの表現では、どのような情報が返ってくる可能性があるか考えて設計します。例えば、上記
の URI に HTTP GET リクエストを送信した場合、以下のような HTTP ステータスコードが返ってくる可能
性があると考えられます。
•
•
•
•
200 OK
400 Bad Request
404 Not Found
500 Internal Server Error
:
:
:
:
ID10 番の本が存在し、情報を DB から取得できた場合。
ID に数字以外の値が入力された場合。
ID10 番の本が存在しなかった場合。
予期せぬシステム側のエラーが発生した場合。
この設計を、全てのオペレーションに対して行います。また、オペレーション以外にも、システムとして
返すべき HTTP ステータスコードなども、ここで設計する必要があります。例えば、アカウントの新規作成
を行うオペレーションを実装しない場合、システムは、http://<hostname>/accounts に対する HTTP POST
リクエストに対して、405 Method Not Allowed を返すべきです。
2-2-4 表現の詳細設計
概要設計の内容を、より詳細化します。特に、以下の内容を決定します。
•
•
エンティティー・ボディーを持つリクエストとレスポンスに対して、どのようなフォーマットのメ
ッセージを出力するか。
メッセージのフォーマットについては、データの表現形式として、JSON や XML、
Atom、YAML、CSV、HTML、microformat など、様々なものが考えられます。一般に
は、JavaScript との親和性が高い JSON が選択されることが多いようです。その Web
サービスを呼び出すクライアントに応じて、選択します。内容については、リストが返っ
てくるのか、どのようにエラー内容を記述するのか、といった一般的な内容について考
えます。特に RESTful Web サービス特有の考慮事項はありませんが、独自のエラー
コードを作成する場合は、HTTP ステータスコードとの重複に注意してください。必要
だとすれば、500 Internal Server Error を詳細に分類するためなどに利用するべきで
す。
HATEOAS をどのように実現するか(接続性)。
-9-
HATEOAS とは、Hypermedia As The Engine Of Application State(アプリケーショ
ン状態のエンジンとしてのハイパーメディア)の略で、"アプリケーション状態をサーバ
ーが保持しない(ステートレスであるため)代わりに、ハイパーメディア内に、関連する
URI が含まれているべきである"というアーキテクチャー・スタイルです。Web の最も基
本的で重要な仕組みである"リンク"によって、互いのリソースを結びつけることが重要
という思想になります。検索結果が非常に多い場合、HTML の場合、"次のページ"や
"前のページ"というリンクが用意されることが多いですが、これを RESTful Web サー
ビスにおいても実現することで、クライアントはサービスの全体像を理解して URI を組
み立てる操作をしなくても、レスポンスの中に含まれる URI を辿っていくだけで、一連
の処理を完了することができるようになります。
例えば、本の検索結果において、一度に返す件数が 25 件と決まっている場合、次
のような URI をメッセージや HTTP ヘッダーに含めることで、全件データを返すことな
く、クライアントに容易に処理させることができます。
http://<hostname>/books?start=26&size=25
2-2-5 設計の注意事項
ここでは、設計の注意事項についてまとめます。
•
•
•
•
•
•
method=delete や action=create などの動詞を与えて、それによって実行される内容を大
きく分岐させるような設計にしない。
HTTP メソッドで分離すべきか、さもなくばリソースの分割が必要です。
リソース名に動詞を含めない。
実行する内容は、HTTP メソッドによって示します。
HTTP ステータスコードに類似した、独自のエラーコードをエンティティー・ボディーに含め
ない。
HTTP ステータスコードで大きく分け、その中でハンドリングしたいエラーを、エンテ
ィティー・ボディーもしくは HTTP ヘッダーを利用して分けるべきです。
日本語を URI に含めるときは、UTF-8 として URI エンコード(パーセントエンコード)する
JavaScript に含まれる URI エンコード関数は、標準で UTF-8 での URI エンコード
(パーセントエンコード)を行います。
あまり長い URI にならないように注意する。
一部のブラウザーは、2083 文字以上の URI を処理することができないため、非常
に長いパラメーター(URI エンコードされた日本語の文章など)が、クエリー・パラメータ
やパスに含まれないように注意します。
HTTP ステータスコードの 200 OK と 400 Bad Request を乱用しない。
例えば、リソースが新規作成された場合を表す"201 Created"や、非同期処理など
に よ っ て 、 正 常 に 処 理 依 頼 が 為 さ れ 、 後 で 処 理 が 実 行 さ れ る 場 合 を 表 す "202
Accepted"、WebDAV 仕様では、複数の処理結果を返すために、"207 Multi-Status"
が用意されています。また、"409 Conflict"は、リクエストで期待される状態と、リソー
スの状態が矛盾した場合などに利用できます。
ただし、これらのステータスコードでは、含める必要のある、もしくは含めるべき
HTTP ヘッダーなども規定されていますので、RFC で規定された仕様に則して利用す
る必要があります。
- 10 -
3 Web 2.0 FP の適用
この章では、WAS への Web 2.0 FP の適用方法を説明します。
3-1 WAS ランタイムへの Web 2.0 FP の適用
Web 2.0 FP をインストールするには、事前に WAS のインストールが必要です。
下記の Web 2.0 FP のサイトから、”Click here to get WebSphere Application Server Feature Pack for
Web 2.0” ボ タ ン を ク リ ッ ク し 、 Web 2.0 FP を ダ ウ ン ロ ー ド し ま す 。 Web 2.0 FP V1.0.1 は 、 WAS
V6.0/V6.1/V7.0 に適用可能です。ただし、WAS V6.0 では JAX-RS の機能を使用することはできませ
ん。これは、JAX-RS はアノテーションを前提とした仕様であり、WAS V6.1 のベースとなる JDK 1.5 以上
が必要なためです。
•
IBM WebSphere「WebSphere Application Server Feature Pack for Web 2.0」
http://www-01.ibm.com/software/webservers/appserv/was/featurepacks/web20/
ダウンロード・サイトにアクセスすると、下記のように 3 種類のダウンロード可能なファイルがあります。
初めて Web 2.0 FP を適用される方は、上 2 つの中から、適用する環境に適した圧縮形式のファイル
「7.x-6.x-WS-WAS-WEB2FEP-MultiOS.*」をダウンロードしてください。すでに、Web 2.0 FP のバージョ
ン 1.0.0 をインストールしている環境を Web 2.0 FP バージョン 1.0.1 の環境にアップグレードする場合に
は、一番下の「1.0.1-WS-WASWeb20-FP0000000.pak」をダウンロードしてください。
インストール方法の詳細やサイレント・インストールの方法は、下記の Information Center の記載を参
照ください。
•
Web 2.0 FP Information Center 「分散オペレーティング・システムでの Feature Pack
for Web 2.0 のインストール」
- 11 -
•
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.inst
allation.webfep20nd.doc/info/ae/ae/tins_install_web20.html
Web 2.0 FP Information Center 「Feature Pack for Web 2.0 のサイレント・インストー
ル」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.insta
llation.webfep20nd.doc/info/ae/ae/tins_runSilent_web20.html
Web 2.0 FP V1.0.0 からアップグレードする場合には、「Update Installer による Feature Pack for Web
2.0 への保守の適用」を参照ください。アップグレードする場合は、通常の Fix Pack の適用と同様に、
Update Installer を使用してアップグレードを行ないます。
•
Web 2.0 FP Information Center 「Update Installer による Feature Pack for Web 2.0
への保守の適用」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.insta
llation.webfep20nd.doc/info/ae/ae/tins_updi_web20.html
以降では、ウィザードを使用した Web 2.0 FP 1.0.1 の新規インストールの手順の概要を説明します。
1). ダウンロードした Web 2.0 FP の「7.x-6.x-WS-WAS-WEB2FEP-MultiOS.*」のファイルを任意
のディレクトリーに展開します。展開先に複数のファイル/ディレクトリーが生成されますので、空
のディレクトリーに展開することをお勧めします。
2). デプロイメント・マネージャー、ノード・エージェント、アプリケーション・サーバーが稼動している
場合には、停止します。
3). 展開したディレクトリーに移動し、コマンド・ラインから下記のように、WAS の JVM のパスをオプ
ションに指定し、install コマンドを実行します。
#Unix/Linux の場合
./install -is:javahome <app_server_root>/java
#Windows の場合
install -is:javahome <app_server_root>\java
下記は、Windows のコマンド・プロンプトでの実行例です。WAS のインストール・ディレクトリー
などにスペースが含まれる場合には、JVM のパスを 2 重引用符(”)で囲みます。
- 12 -
4). 下記のウィザード画面が表示されますので、ウィザードにしたがってインストールを行ないま
す。途中、Web 2.0 FP の適用先となる WAS のインストール・ディレクトリーの入力が必要で
す。
5). インストールが完了すると下記の画面が表示されます。
6). インストール完了後、<app_server_root>/bin ディレクトリーの versionInfo コマンドを実行する
ことで、適用が確認できます。
C:\Program Files\IBM\WebSphere\AppServer\bin>versionInfo
WVER0010I: Copyright (c) IBM Corporation 2002, 2005, 2008; All rights reserved.
WVER0012I: VersionInfo reporter バージョン 1.15.1.26、日付 8/9/08
~~~途中略~~~
Product List
-------------------------------------------------------------------------------BASE
インストール済み
- 13 -
WEB2FEP
インストール済み
インストール済み製品
-------------------------------------------------------------------------------名前
IBM WebSphere Application Server
バージョン
7.0.0.7
ID
BASE
ビルド・レベル
ビルド日
cf070942.55
10/24/09
アーキテクチャー
Intel (32 bit)
インストール済み製品
-------------------------------------------------------------------------------名前
Web 2.0 Feature Pack
バージョン
1.0.1.0
ID
WEB2FEP
ビルド・レベル
ビルド日
web21012.5
3/15/10
アーキテクチャー
Intel (32 bit)
-------------------------------------------------------------------------------~~~以下略~~~
JAX-RS に関連する下記のセキュリティーの修正プログラムが公開されています。Web 2.0 FP をインス
トールする場合には、2010 年 10 月下旬に公開予定の WAS V7.0.0.13 以降、もしくは、現在公開されて
いる修正プログラムを、インストールとあわせて適用してください。修正プログラムは下記サイト上のリンク
からダウンロードできます。修正プログラムの適用方法は、Update Installer を使用します。通常の Fix や
FixPack の適用方法と同様です。
•
WAS Support「Potential security exposure with IBM WebSphere Application Server
with JAX-WS or JAX-RS (PM14844, PM14847, PM14765)」
http://www-01.ibm.com/support/docview.wss?uid=swg21433581
以上で、WAS への Web 2.0 FP の適用は完了です。既存プロファイルの拡張などは必要ありませんの
で、新規プロファイルを作成せずに、既存プロファイル上でも、Web 2.0 FP の機能を使用したアプリケー
ションを稼動させることが可能です。
もし、インストールに失敗した場合などは、下記サイトのトラブルシューティングのセクションを参照くだ
さい。
•
Web 2.0 FP Information Center 「分散オペレーティング・システムでの Feature Pack
for Web 2.0 のインストール」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.insta
llation.webfep20nd.doc/info/ae/ae/tins_install_web20.html
- 14 -
Web 2.0 FP を適用すると、適用した WAS のインストール・ディレクトリーの直下に” web2fep”ディレクトリ
ーが作成されます。このディレクトリー内にドキュメントや、ライブラリー(jar ファイル)、サンプル・アプリケ
ーションがありますので、ご利用ください。
3-2 開発環境の設定
Rational Application Developer (以降、RAD) V7.5.5 以降において、JAX-RS の開発がサポートされて
います。
RAD V7.5.5 で、JAX-RS の開発環境を設定するには、RAD の WAS V7 または V6.1 テスト・サーバー
に Web 2.0 FP を適用します。適用方法は、Installation Manager を使用してテスト・サーバーに Web 2.0
FP を適用します。
1). [スタート]-[すべてのプログラム]-[IBM Installation Manager]-[IBM Installation Manager]を選
択し、Installation Manager を起動し、[変更]ボタンをクリックします。
2). [パッケージの変更-パッケージ・グループの選択]画面において、RAD が含まれるパッケージ・
グループを選択し、[次へ]をクリックします。
- 15 -
3). [パッケージの変更-インストールする翻訳]の画面は、変更の必要はありません。既存の設定の
まま[次へ]をクリックします。
4). [パッケージの変更-インストールするフィーチャー]の設定において、Web 2.0 FP を適用対象の
WAS テスト・サーバーを展開し、[Feature Pack for Web 2.0]のチェックボックスを選択します。
[次へ]をクリックします。
- 16 -
5). [パッケージの変更-テスト環境の構成]の設定は、変更の必要はありません。既存の設定のま
ま[次へ]をクリックします。
6). [パッケージの変更-要約]画面が表示されますので、追加するフィーチャーに[Feture Pack for
Web 2.0]が表示されていることを確認し、[変更]をクリックします。Web 2.0 FP の適用が開始さ
れます。
- 17 -
7). テスト・サーバーへの Web 2.0 FP の適用が完了すると下記の画面が表示されます。[終了]ボ
タンをクリックして、完了です。
以上で RAD への JAX-RS 開発環境設定は完了です。テスト・サーバーに適用された Web 2.0 FP の
バージョンの確認は「3-1WAS ランタイムへの Web 2.0 FP の適用」の手順6)と同様に versionInfo コマンド
を 使 用 し ま す 。 RAD の テ ス ト ・ サ ー バ ー の versionInfo コ マ ン ド の デ ィ レ ク ト リ ー は
<RAD_install_root>/runtimes/base_v7/bin や<RAD_install_root>/runtimes/base_v61/bin ディレクトリーで
す。
RAD への JAX-RS 開発環境の設定手順は下記の Information Center の記載も参照ください。JAX-RS
ファセットの設定は、Web プロジェクトの作成途中に設定することも可能です。本資料では、後続の「4-2
簡単な JAX-RS アプリケーションの開発」で、Web プロジェクトの作成途中で設定する方法で説明しま
す。
•
•
RAD V7.5.5 Information Center 「JAX-RS」
http://publib.boulder.ibm.com/infocenter/radhelp/v7r5/topic/com.ibm.webservice.wsf
p.doc/topics/cjaxrs.html
RAD V8.0 Information Center 「JAX-RS」
http://publib.boulder.ibm.com/infocenter/radhelp/v8/topic/com.ibm.webservice.doc/to
pics/core/cjaxrs.html
- 18 -
4 JAX-RS プロバイダーの開発
この章では、Web 2.0 FP の JAX-RS ライブラリーを使用した RESTful Web サービスのプロバイダーの
開発方法を説明します。
4-1 JAX-RS 概要
JAX-RS(Java API for RESTful Web Services)は JSR 311 で規定された標準仕様で、RESTful な Web
サービスを標準の API を利用して容易に開発することができます。JAX-RS は Java EE 6 に含まれます
(Java EE 6 には、JAX-RS 1.1 が含まれます)。
JAX-RS の特徴は、Java アノテーションを利用することにより、事前に定義されたクラスやインターフェ
ースの継承/実装などを行うことなく、POJO ベースで開発を行える点です。アノテーションは、クライアント
からの HTTP リクエストの適切な Java クラスのメソッドへのルーティングや、リクエスト・データと呼び出さ
れる Java メソッドのパラメーターへのマッピングなどに使用されます。また、Java オブジェクトを、リソース
の表現であるレスポンス・データ(XML や JSON)に自動的/容易に変換することができます。
URI で識別されるリソースへのアクセスは、通常、特定の URI への HTTP リクエストで行なわれます。
その HTTP リクエストを処理するユーザー定義の JAX-RS のクラスやメソッドを、それぞれリソース・クラ
ス、リソース・メソッドと呼びます。リソース・クラス、リソース・メソッドと、Web 2.0 FP を適用した WAS によっ
て提供される JAX-RS エンジンの関係の概要を下記 図 4-1 に示します。
WAS
JAX-RS エンジン
HTTP
リクエスト
リクエスト
プロセッサー
WAS with Web2.0 FP
Webコンテナー
ライフサイクル
管理
リソース
クラス
インジェクション
コール
データ
WAS
REST
Servlet
HTTP
クライアント
コール
データ
リソース
メソッド
・リクエストの解析
・データフォーマット
変換
・レスポンス生成
リターン
サービス
ロジック
データ
リターン
HTTP
レスポンス
データ
・・・ 開発が必要なもの
図 4-1 JAX-RS の仕組みとコンポーネント
JAX-RS エンジンの REST Servlet が、HTTP クライアントからの HTTP リクエストを受け付けます。次
に、リクエスト・プロセッサーが、リクエストの URI 情報の解析を行い、呼び出すリソース・クラス、リソース・
メソッドを特定します。また、エンティティー・ボディーのデータ・フォーマットの変換も JAX-RS のエンジン
- 19 -
が行います。開発者が開発するのは、リソース・クラス、リソース・メソッドです。また、リソース・クラス、リソ
ース・メソッドに、@Path などのアノテーションを付与することで、JAX-RS エンジンに、そのリソース・クラ
ス、リソース・メソッドが処理する URI などを通知します。
データ・フォーマット変換は、JAX-RS エンジンがデフォルトで提供している機能だけでなく、開発者が
提供するクラスを追加することも可能です。このクラスをプロバイダー(@Provider アノテーションを使用し
て、プロバイダー・クラスを指定します)と呼びます。
リソース・クラス、リソース・メソッドについて、下記の DeveloperWorks の記事に詳しくまとめられていま
すので参考にしてください。
•
DeveloperWorks「Create RESTful Web services with Java technology」
http://www.ibm.com/developerworks/web/library/wa-jaxrs/
4-2 簡単な JAX-RS アプリケーションの開発
この節では、簡単な Hello world の JAX-RS アプリケーションの開発方法を説明し、JAX-RS アプリケ
ーション開発の概要を説明します。
RESTful Web サービスでは、HTTP リクエストに対して、HTTP レスポンスを応答します。この簡単な
JAX-RS アプリケーションの開発では、下記の「例 4-1 HTTP リクエストの例 」の HTTP リクエスト(URL:
http://<hostname>:<port>/<ContextRoot>/<SevletURLMapping>/service/hello への GET リクエスト)に対
して、「例 4-2 HTTP レスポンスの例」の HTTP レスポンス(エンティティー・ボディーに”Hello JAX-RS
Service”の文字列を持つ)を応答するアプリケーションを開発します。
例 4-1 HTTP リクエストの例
GET /MyFirstRESTfulService/jaxrs/service/hello HTTP/1.1
Host: localhost:9080
Accept: text/plain,*/*
例 4-2 HTTP レスポンスの例
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 20
Content-Language: ja-JP
Date: Mon, 28 Jun 2010 08:32:39 GMT
Server: WebSphere Application Server/7.0
Hello JAX-RS Service
前提条件
JAX-RS アプリケーションの開発/実行には、下記の環境が必要です。
•
開発環境
RAD V7.5.5 以降
本資料では、RAD V7.5.5 を使用した手順を説明します。
•
実行環境
WAS V7.0/V6.1 (Web 2.0 FP V1.0.1 を含む)
WAS への Web 2.0 FP の導入方法は、「3-1 WAS ランタイムへの Web 2.0 FP の適
用」を参照ください。
- 20 -
4-2-1 Web プロジェクトの作成
JAX-RS ライブラリーが追加された動的 Web プロジェクトを作成します。
1). RAD のメニューから、[ファイル]-[新規]-[動的 Web プロジェクト]を選択します。
2). 「動的 Web プロジェクト」の設定ウィンドウが表示されます。「プロジェクト名」、「EAR メンバー
シップ」を設定し、「構成」の設定において[IBM JAX-RS Configuration]を選択します。[次へ]
をクリックします。
注) ここで、構成として「IBM JAX-RS Configuration」を選択しなかった場合(構成は一つしか
選択できないため、他の機能を優先することも可能)や、既存の Web プロジェクトに対して、
JAX-RS の開発機能を有効化するには、作成した Web プロジェクトのファセットに「JAX-RS ファ
セット」の追加が必要です。
「JAX-RS ファセット」を追加するには、「プロジェクト・エクスプローラー」や「エンタープライズ・エ
クスプローラー」で、ファセットを追加対象の Web プロジェクトを選択、右クリックし、[プロパティ
ー]を選択します。下記のプロジェクトのプロパティー設定画面において、一覧から[プロジェクト・
ファセット]を選択し、適用するファセットとして[JAX-RS (REST Web サービス)]のチェックボック
スを ON にします。
- 21 -
プロジェクト・ファセットを後から追加した場合には、後続の手順 5)で設定する、JAX-RS ライ
ブラリー追加設定や、サーブレット・マッピングの設定が自動的には設定されません。手動でビ
ルドパスへの JAX-RS ライブラリーの追加や、web.xml に対しての Servlet マッピングの設定が
必要になります。
ビルドパスに追加が必要な JAX-RS ライブラリーの詳細は、下記の Information Center の記
載を参照ください。
•
Web 2.0 FP Information Center 「JAX-RS アプリケーションの開発環境のセットアップ」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web
20fepjaxrs.doc/info/ae/ae/twbs_jaxrs_devenv.html
web.xml への Servlet マッピングの設定は、下記の Information Center の記載を参照ください。
•
Web 2.0 FP Information Center 「JAX-RS サーブレット用 web.xml ファイルの構成」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web
20fepjaxrs.doc/info/ae/ae/twbs_jaxrs_configwebxml.html
3). 「Web モジュール」の設定ウィンドウが表示されます。「コンテキスト・ルート」などを設定し、[次
へ]をクリックします。
4). 「Web 2.0 サーバー・サイド・テクノロジー」の設定ウィンドウが表示されます。そのまま[次へ]を
クリックします。
- 22 -
5). 「 JAX-RS 機 能 」 の 設 定 ウ ィ ン ド ウ が 表 示 さ れ ま す 。 「 ラ イ ブ ラ リ ー 」 の 設 定 で は 、 [IBM
WebSphere JAX-RS Library for WAS 7 <デフォルト>]を選択し、[このアプリケーションにライ
ブラリーを組み込む]チェックボックスを ON にし、[デプロイ]を選択します。[デプロイ]を選択する
ことにより、war ファイルをエクスポートしたときに、JAX-RS の稼動に必要なライブラリーファイ
ルを war ファイルに含めてエクスポートすることができます。「JAX-RS サーブレット・クラス名」
は、デフォルトで指定されている[com.ibm.websphere.jaxrs.server.IBMRestServlet]を指定し
ます。「JAX-RS サーブレット名」、「URL マッピング・パターン(ServletURLMapping)」は任意
の値を設定可能です。RESTful な Web サービスには、下記の URI でアクセスすることになりま
す。[終了]をクリックします。
”http://<hostname>:<port>/<ContextRoot>/<SevletURLMapping>/<ResourceURI>”
4-2-2 リソース・クラス、リソース・メソッドの作成
URI:”http://<hostname>:<port>/<ContextRoot>/<ServletURLMapping>/service/hello”への GET リクエ
ストを処理するリソース・クラスとリソース・メソッドを作成します。
1). 新規 Java クラスを作成します。作成した Web プロジェクトの src フォルダを右クリックし、[新
規]-[クラス]を選択します。「新規 Java クラス」ウィザードで、「パッケージ」、「名前(クラス名)」
を指定し、[終了]をクリックします。この例では、パッケージ、名前は、下記のとおりとします。
パッケージ:com.ise.myfirstrest (任意)
名前(クラス名) :MyFirstRESTService (任意)
尚、特別なクラスやインターフェースを継承、実装する必要はありません。
- 23 -
2). 下記のように、リソース・クラス、リソース・メソッドを実装します。
•
クラス定義に@Path アノテーションを追加し、value の値として「/service」を指定します。
•
クラスに引数なしの public なコンストラクターを追加します。
•
String オブジェクトを戻すメソッドを追加します。
•
メソッドに@GET アノテーションと@Path アノテーションを追加し、@Path アノテーションの
value の値として「/hello」を指定します。
@Path アノテーション:このアノテーションで、リクエスト URI に対して処理を行なうクラスやメソッド
を指定します。
@GET アノテーション:このアノテーションで、HTTP の GET メソッドに対して処理を行なうメソッド
を指定します(サーブレットの doGet メソッドを、アノテーションを使用して設定するようなイメージ
です)。
4-2-3 JAX-RS Application クラスのサブクラスの作成
Java EE 6 実装ではない Web コンテナーを使用する場合(WAS V7 with Web 2.0 Feature Pack の環境
は Java EE 5 実装です)、javax.ws.rs.core.Application クラスを継承したクラスを作成し、JAX-RS エンジン
に対して JAX-RS のリソース・クラスを通知する必要があります。
1). 新規 Java クラスを作成します。作成した Web プロジェクトの src フォルダを右クリックし、[新
規]-[クラス]を選択します。「新規 Java クラス」ウィザードで、「パッケージ」、「名前(クラス名)」
を指定し、スーパークラスとして「javax.ws.rs.core.Application」を指定し、[終了]をクリックし
ます。
パッケージ:com.ise.myfirstrest (任意)
名前(クラス名):MyApplication (任意)
スーパークラス:javax.ws.rs.core.Application
- 24 -
2). getClasses メソッドを実装します。下記のように、4-2-2の1).で作成したリソース・クラスを内容
として含む Set オブジェクトをリターンするようにします。
この getClasses メソッドでは、この Web モジュール内のすべてのリソース・クラスを Set オブジ
ェクトの内容として戻す必要があります。今回の例では、リソース・クラスは、
「com.ise.myfirstrest.MyFirstRESTService.class」の 1 つのみです。
3). 作成した Application のサブクラスを web.xml に登録します。これにより、JAX-RS ランタイムが
リソース・クラスを取得します。web.xml ファイルを開き、IBMRestServlet が指定されている
<servlet>要素の<init-param>定義に下記の定義を追加します。
表 4-1 servlet 要素の init-param の設定
設定要素
値
param-name
javax.ws.rs.Application
param-value
com.ise.myfirstrest.MyApplication
備考
固定値
4-2-3の1).で作成した Application クラスのサブ
クラス
4-2-4 稼動確認
作成した Web アプリケーションを RAD の WAS テスト・サーバーまたは、WAS にデプロイします。Web
ブラウザーから下記の URI に GET リクエストを行ないます。
http://<hostname>:<port>/<ContextRoot>/<ServletURLMapping>/service/hello
- 25 -
今回の例の場合は、下記の URI にリクエストを行ないます。尚、WAS が HTTP リクエストをリッスンするデ
フォルトのポート番号は、9080 です。
http://<hostname>:<port>/MyFirstRESTfulService/jaxrs/service/hello
下記のように、リソース・メソッドに記述した” Hello JAX-RS Service”の文字列が返ってくれば成功です。
4-3 JAX-RS アプリケーションの開発
この節では、より詳細な JAX-RS アプリケーションの開発方法を説明します。
4-3-1 リソース・クラス、リソース・メソッドの指定
リソース・クラス、リソース・メソッドの指定には@Path アノテーション(java.ws.rs.Path)を使用します。ま
た、リソース・クラスの Java メソッドが要求を受け付ける HTTP メソッドを指定するには、下記の表の
@GET、@POST などの HTTP メソッドをあらわすアノテーションを付与します。
表 4-2 HTTP メソッドを識別するアノテーション
アノテーション
説明
@GET
HTTP GET メソッドを処理する Java メソッドに指定する。
@POST
HTTP POST メソッドを処理する Java メソッドに指定する。
@PUT
HTTP PUT メソッドを処理する Java メソッドに指定する。
@DELETE
HTTP DELETE メソッドを処理する Java メソッドに指定する。
@HEAD
HTTP HEAD メソッドを処理する Java メソッドに指定する。
@HttpMethod
その他の HTTP メソッドに対応するメソッド・アノテーションを作成するためのアノテ
ーション(このアノテーションを、そのままメソッドに指定はできません)。
(アノテーションのフルパスは、javax.ws.rs.core.GET、javax.ws.rs.core.POST などです)
例えば、下記の表 4-1 の各 URI リクエストを処理する MemberResource リソース・クラスのアノテーショ
ン定義は下記の例 4-3 ように指定します。
表 4-3 HTTP メソッドを識別するアノテーション
相対 URI
HTTP メソッド
/members
GET
/members/id2
GET
/members/id2
PUT
Java リソース・メソッド
listMembers
getMemberID2
updateMemberID2
例 4-3 リソース・クラス/リソース・メソッドを指定するサンプル・コード
package com.ise.rsguide.resource;
- 26 -
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
@Path("members")
public class MemberResource {
public MemberResource() {}
@GET
public String listMembers(){
StringBuilder sb = new StringBuilder();
sb.append("id,name\n").append("2,阿部\n").append("4,田中");
return sb.toString();
}
@Path("id2")
@GET
public String getMemberID2(){
StringBuilder sb = new StringBuilder();
sb.append("2,阿部,1981");
return sb.toString();
}
@Path("id2")
@PUT
public void updateMemberID2(String body){
System.out.println(body);
}
}
補足 1)
Path アノテーションは値を一つしか持たない単一アノテーションですので、「value=」を省略することが
可能です。つまり、下記のどちらも、同じ意味を表します。
•
@Path(value=”members”)
•
@Path(“members”)
補足 2)
Path アノテーションの値は、相対パスを指定します。また、その規定となるパスは、”/”で終わることが
仮定されています。つまり、Path アノテーションの最初と最後の”/”は、存在の有無に関わらず、同じ URI
をあらわします。つまり、下記のいずれの記述でも同じリクエストを処理します。
•
@Path(“members”)
•
@Path(“/members”)
•
@Path(“members/”)
•
@Path(“/members/”)
- 27 -
補足 3)
リクエスト URI のパス指定における最後の”/”の有無も、処理される Java メソッドの判定には影響しま
せん。例 4-3 の場合、下記の URI への GET メソッドを送信した場合、処理されるメソッドは下記のよう
になります。
表 4-4 URI とリソース・メソッドのマッピング例
URI
処理する Java メソッド
/members
listMembers
/members/
listMembers
/members?name=abe listMembers
/memb
/membersid2
/members/id2
/members/id2/
/members/id2/name
なし(404 エラー)
/members/id
なし(404 エラー)
備考
クエリー・パラメータの有無は@Path でのパス
の判定には使用されない
なし(404 エラー)
getMemberID2
getMemberID2
/id2 以降にも/で区切られた URI が継続するリ
ク エ ス ト は 処 理 さ れ な い ( も し 、
getMemberID2 メソッドの@Path アノテーショ
ンの値が ”id2/name”であれば、処理されま
す)。
なし(404 エラー)
4-3-1-1 @Path の値に変数の使用
前節では、@Path の値として、文字列の指定を紹介しましたが、@Path の値としては、文字列のみで
はなく、変数と正規表現を使用することができます。
変数は、”{“ と ”}” で、変数名を囲みます。変数は、”/” 以外の任意の文字(1 文字以上)がマッチす
るワイルドカードです。
下記の getMemberByID()メソッドの例では、/members/2 や/members/4 のような”/members/(任意の文
字列)”の URI リクエスト(HTTP の GET)に対して、getMemberByID()メソッドが処理を行ないます。ただ
し、/members/2/4 のように、(任意の文字列)に ”/” が含まれるリクエストはマッチしませんので、ご注意く
ださい。
また、変数と固定の文字列を組み合わせることもできますので、下記の getMemberByPosition()メソッ
ドの例では、”/members/position-(任意の文字列)”の URI のリクエストに対する処理を行ないます。
尚、”/members/position-DF”の URI リクエストは、@Path(“position-{pos}”)と@Path(“{id}”)の両方にマッ
チしますが、この場合には、マッチした固定文字の数(この例では、”position-{pos}”は”position-”の 10
文字、”{id}”は固定文字がないため、0 文字)が多い方の@Path(“position-{pos}”)のアノテーションが付
与されたメソッドが選択されます。
例 4-4 @Path の値に変数を使用したサンプル・コード
package com.ise.rsguide.resource;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
- 28 -
@Path("members")
public class MemberResource {
public MemberResource() {}
@Path("{id}")
@GET
public String getMemberByID(@PathParam(value="id")String id){
StringBuilder sb = new StringBuilder();
if(id.equals("2")){
sb.append("2,阿部");
}else if(id.equals("4")){
sb.append("4,田中");
}else{
sb.append("該当する ID のメンバーは存在しません。");
}
return sb.toString();
}
@Path("Position-{pos}")
@GET
public String getMemberByPosition(@PathParam(value="pos")String id){
StringBuilder sb = new StringBuilder();
if(id.equals("GK")){
sb.append("川口,川島");
}else if(id.equals("DF")){
sb.append("中澤,田中");
}else{
sb.append("該当するポジションは存在しません。");
}
return sb.toString();
}
}
尚、上記の例では、@Path アノテーションで指定した変数にマッチする値を、getMemberByID メソッド
の引数として取得しています。その方法については、「4-3-3 HTTP リクエスト情報の取得」で後述しま
す。
4-3-1-2 @Path の値に正規表現の使用
正規表現を使用した@Path アノテーションの値は下記の構文で指定します。
{(変数名) : (正規表現)}
下記の例では、例 4-4 の getMemberByID()メソッドが処理する URI リクエストを/members/に続いて、
1 文字以上の数字のみを認める(¥¥d+)ように修正した例です。
- 29 -
例 4-5 @Path の値に正規表現を使用した例
@Path("{ id : \\d+}")
@GET
public String getMemberByID(@PathParam(value="id")String id){
StringBuilder sb = new StringBuilder();
if(id.equals("2")){
sb.append("2,阿部");
}else if(id.equals("4")){
sb.append("4,田中");
}else{
sb.append("該当する ID のメンバーは存在しません。");
}
return sb.toString();
}
尚、正規表現の記述自体については、javadoc の java.util.regex.Pattern クラスの記載等を参照くださ
い。
•
Java 6 API Document「java.util.regex.Pattern クラス」
http://java.sun.com/javase/ja/6/docs/ja/api/java/util/regex/Pattern.html
また、正規表現を使用した場合の注意点として、変数のときとは異なり、正規表現を使用した場合に
は、”/”(スラッシュ)も含んで、評価が行なわれます(変数を使用したときには、デフォルトの正規表現の評
価式として” [^/]+”が適用されます)。したがって、上記の例の”¥¥d+”の評価式を、任意の文字をあらわ
す ”.+” を 評 価 式 に 変 更 し た 場 合 、 /members/123 や /members/aaa の URI の み で は な く 、
/members/aaa/bbb のような途中に”/”を含む URI にもマッチします。
補足)
上記のコード例において、任意の数字をあらわす正規表現として、”¥¥d”と”¥”記号を 2 回繰り返してい
ますが、これは、java のソースコードでは、”¥”記号はエスケープシーケンスとして解釈されるため、ソー
スコードがコンパイルされた結果として、”¥”記号をあらわすように、”¥”記号を 2 回繰り返しています。”¥”
記号が Java バイトコードコンパイラによって解釈されないようにするには、正規表現を表す文字列リテ
ラル内で”¥”記号を 2 つ続ける必要があります。
4-3-2 エンティティー・ボディーの取得/生成
この節では、HTTP リクエストとレスポンスにおける、HTTP エンティティー・ボディー(メッセージ・ボディ
ー)の取得と生成について説明します。HTTP リクエストのエンティティー・ボディーは、JAX-RS のリソー
ス・メソッドの Java メソッドの引数の 1 つとして取得することができます。また、HTTP レスポンスのエンティ
ティー・ボディーの内容は、リソース・メソッドの戻り値(または、戻り値の javax.ws.rs.core.Response オブジ
ェクトの entity データ)が変換されます。Response クラスについては、「4-3-4レスポンス HTTP ヘッダーの
設定」で後述します。このように、エンティティー・ボディーと Java オブジェクトの相互変換を行なうクラス
を Provider クラスと呼びます。
- 30 -
Web 2.0 FP の JAX-RS のエンジンには、下記の表の Java タイプと HTTP エンティティー・ボディーの変
換を行なうデフォルト Provider があります。また、Provider クラスを実装することで、ユーザー独自にカス
タマイズすることも可能です。
表 4-5 Web 2.0 FP がサポートするエンティティー・ボディーをマップする Java タイプ
JAX-RS
java タイプ
備考
エンジン
のタイプ
標準
byte[]
標準
java.lang.String
標準
java.io.InputStream
バイトストリームとの相互変換が必要な場合に使用。
標準
java.io.Reader
文字ストリームとの相互変換が必要な場合に使用。
標準
java.io.File
標準
javax.activation.DataSource
標準
javax.xml.transform.Source
コンテンツのタイプが XML (Content-Type が、
text/xml, application/xml, application/*+xml)の場合
に使用可能。一般的にリクエスト・データを XSLT 変
換する場合に使用します。
標準
javax.xml.bind.JAXBElement や
コンテンツのタイプが XML (Content-Type が、
ユーザー提供の JAXB クラス
text/xml, application/xml, application/*+xml) の場
合に使用可能。リクエストまたはレスポンス・データを
JAXB のオブジェクトとして扱うことができます。また、
IBM の拡張機能により、JSON 形式のデータを
JAXB のオブジェクトに変換することも可能です。
標準
MaltivaluedMap<String, String>
コンテンツのタイプがフォーム・データ(Content-Type
が、application/x-www-form-urlencoded) の場合に
使用可能。
標準
javax.ws.rs.core.StreamingOutput
レスポンス・ボディーの生成時のみ使用可能。
Web 2.0 com.ibm.json.java.JSONArray
コンテンツのタイプが JSON 形式の場合に使用可
FP
com.ibm.json.java.JSONObject
能。
Web 2.0 org.apache.wink.common.model.ato
コンテンツのタイプが Atom 形式の場合に使用可
FP
m.AtomEntry
能。
org.apache.wink.common.model.ato
m.AtomFeed
org.apache.wink.common.model.syn
d.SyndEntry
org.apache.wink.common.model.syn
d.SyndFeed
Web 2.0 org.apache.abdera.model.Entry
コンテンツのタイプが Atom 形式の場合に使用可
FP
org.apache.abdera.model.Feed
能。
Web 2.0 org.apache.wink.common.model.mul マ ル チ パ ー ト の コ ン テ ン ツ (Content-Type が 、
FP
tipart.InMultiPart
multipart/*)を扱う場合に使用。InMultiPart を要求デ
org.apache.wink.common.model.mul ータの受信時に、OutMultiPart を応答データの生成
時に使用。
tipart.BufferedInMultiPart
org.apache.wink.common.model.mul
tipart.OutMultiPart
org.apache.wink.common.model.mul
- 31 -
tipart.BufferedOutMultiPart
その他にも、Atom Publishing Protocol や RSS、CSV などのデータ・フォーマットとの変換を行なう
Provider が Apache Wink の実装により提供されています。詳細は「参考資料」の Apache Wink の
Developer Guide を参照ください。
例えば、下記のように、String 型の引数、戻り値をリソース・メソッドで指定することで、HTTP のエンティ
ティー・ボディーを、リソース・メソッドの中では String 型で操作することができます。
例 4-6 リソース・メソッドの引数、戻り値として String を指定した例
package com.ise.rsguide.resource;
import javax.ws.rs.Path;
import javax.ws.rs.Post;
@Path("members")
public class MemberResource {
public MemberResource() {}
@Path("cheer")
@POST
public String receiveCheer(String body){
System.out.println("応援メッセージ["+body+"]");
return "応援メッセージ["+body+"]を受け付けました";
}
}
尚、エンティティー・ボディーをリソース・メソッドの引数となる Java の String 型の変数に変換するときの
文字コードは、HTTP の Content-Type ヘッダーの charset の値を使用して JAX-RS ランタイムが変換しま
す。
後続の「4-3-2-2 XML コンテンツの送受信」と「4-3-2-3 JSON コンテンツの送受信」で、XML と JSON
コンテンツの送受信の方法を説明します。
Provider クラスを独自に実装する方法については、下記の InfoCenter の記載を参照ください。
Web 2.0 FP Information Center「カスタム・エンティティー・フォーマットの実装」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web20fepjaxrs.d
oc/info/ae/ae/twbs_jaxrs_customentityformats_impl.html
また、Web 2.0 FP がデフォルトで提供する Provider クラス以外を使用することも可能です。下記の
DeveloperWorks の記事を参考にしてください。
DeveloperWorks「Jackson JSON プロセッサーと Apache Wink を組み合わせて使う」
http://www.ibm.com/developerworks/jp/web/library/wa-aj-jackson/
- 32 -
4-3-2-1 Content-Type によるリソース・メソッドの選択
「4-3-1 リソース・クラス、リソース・メソッドの指定」において、@Path アノテーションと HTTP メソッド識別
子のアノテーションによるリソース・メソッドの選択について説明しましたが、エンティティー・ボディーの形
式に応じて、リソース・メソッドを選択/制限できます。
コンテンツの内容に応じて、リソース・メソッドを選択/制限するには、@Consumes と@Produces アノテー
ションを使用します。
表 4-6 Content-Type に応じてリソース・メソッドを選択するアノテーション
アノテーション
説明
@Consumes
@Consumes アノテーションは、value 属性を持ち、そのリソース・メソッドが要求を受
信可能なメディア・タイプ(application/xml や application/json など)を指定します。
JAX-RS ランタイムが HTTP リクエストの Content-Type ヘッダーの値に応じて、その
リソース・メソッドが呼び出し可能か否かを判別します。
@Produces
@Produces アノテーションも、value 属性を持ち、そのリソース・メソッドが応答可能
なメディア・タイプを指定します。
JAX-RS ランタイムが HTTP リクエストの Accept ヘッダーの値に応じて、そのリソー
ス・メソッドが呼び出し可能か否かを判別します。
(アノテーションのフルパスは、javax.ws.rs.core.Consumes、javax.ws.rs.core.Produces です)
@Consumes、@Produces アノテーションの value 属性には、一つのメディア・タイプだけではなく、複数
のメディア・タイプをカンマ(”,”)で区切って指定することが可能です。また、メディア・タイプの指定には、
アスタリスク(“*”)を使用したワイルドカードを指定することもできます。下記の例のように指定することが
可能です。また、デフォルト値は、”*/*”です。@Consumes や@Produces のアノテーションが付与されて
いないリソース・メソッドは、任意のメディア・タイプの要求/応答を処理できるとみなされます。
例 4-7 @Consumes と@Produces のアノテーションの使用例
@POST
@Path("player")
@Consumes("*/xml,application/*+xml")
@Produces("*/xml")
public Player createPlayer(Player player){
…
}
尚、@Consumes アノテーションで指定したメディア・タイプを満たさないリクエストを受信した場合、
JAX-RS ランタイムが、「415 Unsupported Media Type」応答を返します。また、@Produces アノテーション
で指定したメディア・タイプを満たさないリクエストを受信した場合は、「406 Not Acceptable」を返します。
4-3-2-2 XML コンテンツの送受信
XML データを処理するために、JAX-RS では、JAXB (Java Architecture for XML Binding) オブジェ
クトを要求エンティティー・パラメーター(リソース・メソッドの引数)および応答エンティティー(リソース・メソ
ッドの戻り値、または戻り値の Response オブジェクトの entity データ)とすることができます。JAXB を使用
することで、XML と Java オブジェクトのデータ・バインディングを容易に行なうことができます。
下記の例 4-8 のような、XML インスタンス文書を POST メソッドで送信して、サーバー側で登録を行
い、下記の例 4-9 のような、XML インスタンス文書のデータを GET メソッドで取得する場合を例に説明
します。
- 33 -
例 4-8 サンプル要求 XML データ
<player id="2">
<name>阿部</name>
<position>MF</position>
</player>
例 4-9 サンプル応答 XML データ
<team>
<player id="2">
<name>阿部</name>
<position>MF</position>
</player>
<player id="4">
<name>田中</name>
<position>DF</position>
</player>
</team>
直接上記のインスタンス文書にマッピングされる JAXB クラスを直接作成することも可能ですが、
JAXB クラスは XML Schema 定義から自動生成することができますので、ここでは、XML Schema 定義を
使用して、JAXB クラスを作成します。
上記 2 つのインスタンス文書を表す XML Schema 定義は下記のように定義することができます。
例 4-10 Team.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="team">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="player" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="player">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" />
<xsd:element name="position" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
- 34 -
この XML Schema を入力値として、JAXB クラスを生成することができます。WAS の bin ディレクトリー
の xjc コマンドを使用することで、JAXB クラスを生成することができます。xjc コマンドの使用方法の詳細
は下記の Information Center の記載を参照ください。
•
WAS V7 Information Center 「JAXB アプリケーションの xjc コマンド」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.nd.d
oc/info/ae/ae/rwbs_xjc.html
ここでは、RAD のウィザードを使用して、JAXB クラスを作成します。RAD のプロジェクト・エクスプロー
ラーで入力値となる XML Schema ファイルを選択、右クリックし、[生成]-[Java]を選択します。Java の生成
ウィザードが表示されますので、”生成プログラム”として「Java Bean の JAXB スキーマ」を選択し、[次
へ]ボタンをクリックします。
XML スキーマの選択画面が表示されます。”ターゲット Java コンテナー”として、JAXB クラスの生成
先のプロジェクトのソースディレクトリー、”ターゲット・パッケージ”として、生成先のパッケージを指定し、
[終了]をクリックします。
Team.xsd を入力とした場合には、下記の 3 つのクラスが生成されます。
•
Player.java
•
Team.java
•
ObjectFactory.java
Player.java の抜粋を下記に記します。String 型の name, position, id の 3 つのインスタンス変数と、そ
れぞれの setter、getter メソッドを持つシンプルなクラスです。name, position, id の 3 つを引数に取るコン
ストラクターを追加しています。
例 4-11 Player.java
package com.ise.rsguide.jaxb;
- 35 -
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"name",
"position"
})
@XmlRootElement(name = "player")
public class Player {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String position;
@XmlAttribute
protected String id;
//手動で追加したコンストラクター
public Player(String name, String position, String id){
this.name = name;
this.position = position;
this.id = id;
}
public Player(){}
// name, position, id の setter、getter メソッド
…
}
また、Team.java の抜粋は下記のとおりです。Player オブジェクトを内容として持つ List 型のインスタン
ス変数 player とその getter メソッドが生成されます。
例 4-12 Team.java
package com.ise.rsguide.jaxb;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
- 36 -
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"player"
})
@XmlRootElement(name = "team")
public class Team {
@XmlElement(required = true)
protected List<Player> player;
public List<Player> getPlayer() {
if (player == null) {
player = new ArrayList<Player>();
}
return this.player;
}
}
これで、準備が整いましたので、XML データの送受信を行なう JAX-RS リソース・メソッドの開発を行
ないます。下記のように、リソース・メソッドの引数(addPlayerXML メソッド)や戻り値(listPlayersXML メソッ
ド)に JAXB のオブジェクトを指定することで、メソッド内部では、XML を意識することなく JAXB のオブジ
ェクトを扱うことができます。
例 4-13 XML を送受信するサンプル・コード
package com.ise.rsguide.resource;
import java.util.List;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import com.ise.rsguide.jaxb.*;
@Path("xml/team")
public class TeamResourceXML {
public TeamResourceXML(){};
@GET
@Path("players")
@Produces("application/xml")
public Team listXMLPlayers(){
Team team = new Team();
- 37 -
List<Player> playersList = team.getPlayer();
Player player1 = new Player("阿部","MF","2");
Player player2 = new Player("田中","DF","4");
playersList.add(player1);
playersList.add(player2);
return team;
}
@POST
@Path("player")
@Consumes("application/xml")
@Produces("application/xml")
public Player createPlayer(Player player){
System.out.println("[登録選手の番号:"+player.getId()+"]");
System.out.println("[登録選手の名前:"+player.getName()+"]");
System.out.println("[登録選手のポジション:"+player.getPosition()+"]");
return player;
}
}
“http://<hostname>:<port>/<ContextRoot>/<ServletURLMapping>/team/players”の URI に GET リクエ
ストを行なった場合、下記のコンテンツが HTTP レスポンスとして戻ります。
例 4-14 XML の HTTP レスポンスの例
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Language: ja-JP
Content-Length: 200
Date: Wed, 01 Sep 2010 05:33:10 GMT
Server: WebSphere Application Server/7.0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><team><player id="2"><name>阿部</name><
position>MF</position></player><player id="4"><name>田中</name><position>DF</position></player
></team>
XML コンテンツの送受信については、下記の Information Center の記載も参考にしてください。
•
Web 2.0 FP Information Center 「XML コンテンツに JAXB オブジェクトを使用したリソ
ース・メソッドの実装」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web
20fepjaxrs.doc/info/ae/ae/twbs_jaxrs_xmlcontent_jaxb.html
4-3-2-3 JSON コンテンツの送受信
JSON データを処理するために、JAX-RS では、JSON4J ライブラリー(com.ibm.json.java パッケージの
JSONObject クラス、JSONArray クラス)のオブジェクトを要求エンティティー・パラメーター(リソース・メソッ
ドの引数)および応答エンティティー(リソース・メソッドの戻り値、または戻り値の Response オブジェクトの
- 38 -
entity データ)とすることができます。JSON4J ライブラリーを使用することで、JSON データと Java オブジェ
クトのデータ・バインディングを容易に行なうことができます。
下記例 4-15 のような、JSON データを POST メソッドで送信して、サーバー側で登録を行い、下記の例
4-16 のような、JSON データを GET メソッドで取得する場合を例に説明します。
例 4-15 サンプル要求 JSON データ
{"id":10, "name":"Nakamura", "position":"DF"}
例 4-16 サンプル応答 JSON データ
[{"position":"MF","name":"Abe","id":2},{"position":"DF","name":"Tanaka","id":4}]
JSON4J のライブラリーを使用するには、JSON4J.jar を WEB-INF/lib フォルダに配置またはビルドパス
に含める必要があります。JSON4J.jar は、Web 2.0 FP をインストールすると、下記のディレクトリーに保管
されています。
<WAS_install_root>/web2fep/optionalLibraries/JSON4J/JSON4J.jar
また、RAD V7.5.5 をご使用の場合には、下記のディレクトリーに保管されています。
<RAD_install_root>/runtimes/base_stub/web2fep/optionalLibraries/JSON4J/JSON4J.jar
例えば、WEB-INF/lib フォルダに配置する場合には、RAD のプロジェクト・エクスプローラーなどで、
該当の Web プロジェクトの WebContent/WEB-INF/lib フォルダを右クリック [インポート]を選択します。イ
ンポート・ウィザードで、[一般]-[ファイル・システム]を選択し、[次へ]を選択します。
ファイルの選択画面で、JSON4J.jar ファイルを指定します。もし、リモートのマシンに Web 2.0 FP を導
入した場合には、JSON4J.jar ファイルをローカルマシンにコピーしてください。
- 39 -
尚 、 通 常 の Windows の エ ク ス プ ロ ー ラ ー か ら 、 JSON4J.jar を コ ピ ー し 、 RAD 上 の
WebContent/WEB-INF/lib ディレクトリーへペーストすることで、ファイルを配置することもできます。
JSON データの送受信を行なう JAX-RS リソース・メソッドの開発を行ないます。下記のように、リソー
ス・メソッドの引数(addPlayerJSON メソッド)や戻り値(listPlayersJSON メソッド)に JSONObject または
JSONArray のオブジェクトを指定することで、メソッド内部では、JSON を意識することなく Java の
HashMap のオブジェクトとして JSONObject を、ArrayList として JSONArray を扱うことができます。
例 4-17 JSON を送受信するサンプル・コード
package com.ise.rsguide.resource;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;
@Path("json/team")
public class TeamResourceJSON {
public TeamResourceJSON(){};
@Path("players")
@GET
@Produces("application/json")
public JSONArray listXMLPlayers(){
JSONArray playerArray = new JSONArray();
JSONObject player1 = new JSONObject();
player1.put("id", 2);
player1.put("name", "Abe");
player1.put("position", "MF");
playerArray.add(player1);
JSONObject player2 = new JSONObject();
player2.put("id", 4);
player2.put("name", "Tanaka");
player2.put("position", "DF");
playerArray.add(player2);
return playerArray;
- 40 -
}
@Path("player")
@POST
@Consumes("application/json")
@Produces("application/json")
public JSONObject addPlayer(JSONObject player){
System.out.println("[登録選手の番号:"+player.get("id")+"]");
System.out.println("[登録選手の名前:"+player.get("name")+"]");
System.out.println("[登録選手のポジション:"+player.get("position")+"]");
return player;
}
}
“http://<hostname>:<port>/<ContextRoot>/<ServletURLMapping>/json/team/players の URI に GET リ
クエストを行なった場合、下記のコンテンツが HTTP レスポンスとして戻ります。
例 4-18 JSON の HTTP レスポンスの例
HTTP/1.1 200 OK
Content-Type: application/json
Content-Language: ja-JP
Transfer-Encoding: chunked
Date: Wed, 01 Sep 2010 05:59:32 GMT
Server: WebSphere Application Server/7.0
[{"position":"MF","name":"Abe","id":2},{"position":"DF","name":"Tanaka","id":4}
JSON コンテンツの送受信については、下記の Information Center の記載も参考にしてください。
•
Web 2.0 FP Information Center 「IBM JSON4J を使用したリソース・メソッドの実装」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web
20fepjaxrs.doc/info/ae/ae/twbs_jaxrs_jsoncontent_impl.html
4-3-3 HTTP リクエスト情報の取得
JAX-RS では、HTTP リクエストに関するさまざまな情報(リクエスト・パラメータや URI の情報)を、アノテ
ーションを使用したインジェクションにより、リソース・メソッドの引数やリソース・クラスの変数に注入するこ
とができます。
JAX-RS で規定されるリクエスト情報をインジェクトするアノテーションは、下記の表のとおりです。
表 4-7 リクエスト情報のインジェクションに使用できるアノテーション
アノテーション・タイプ
備考
@javax.ws.rs.PathParam
URI Path の一部をパラメーターとして取得します。
@javax.ws.rs.MatrixParam
URI の一部に、”;”で区切ってパラメーターを指定するマトリックス・パ
ラメータを取得します。
@javax.ws.rs.QueryParam
URI の最後に、”?”で区切ってパラメーターを指定するクエリー・パラ
- 41 -
メーターを取得します。
フォーム・データを取得します。
HTTP ヘッダー情報を取得します。
HTTP クッキー情報を取得します。
このアノテーションを使用して、以下の表に記述する HTTP リクエスト
に関連する Java オブジェクトやアプリケーションのデプロイメント環境
のコンテキスト情報を取得します。
@Context アノテーションによって、下記の表の Java オブジェクトをインジェクションできます。
@javax.ws.rs.FormParam
@javax.ws.rs.HeaderParam
@javax.ws.rs.CookieParam
@javax.ws.rs.core.Context
表 4-8 @Context アノテーションでインジェクションできる Java オブジェクト
@Context アノテーションでインジェク 備考
ションできるオブジェクト
javax.ws.rs.core.UriInfo
URI 情報を取得します。
javax.ws.rs.core.HttpHeaders
HTTP ヘッダー情報を取得します。
javax.ws.rs.core.Request
HTTP リクエスト・メソッドとキャッシュ・コントロールを行なうことの
できる Request オブジェクトを取得します。
javax.ws.rs.core.SecurityContext
Java EE セキュリティー・コンテキストを取得します。
javax.ws.rs.core.Application
JAX-RS のアプリケーション・コンテキスト情報を取得します。
Application クラスにコンテキスト情報を事前に記述しておく必
要があります。
(javax.ws.rs.core.ext.Providers)
Provider クラスにおいて、他の Provider クラスをインジェクション
することを意図しており、リソース・クラス/リソース・メソッドでの使
用は意図されていません。
javax.servlet.ServletConfig
サーブレット・コンテナー上で JAX-RS アプリケーションが稼動
する場合には ServletConfig を取得することができます。
javax.servlet.ServletContext
サーブレット・コンテナー上で JAX-RS アプリケーションが稼動
する場合には ServletContext を取得することができます。
javax.servlet.http.HttpServletRequest
サーブレット・コンテナー上で JAX-RS アプリケーションが稼動
する場合には HttpServletRequest を取得することができます。
javax.servlet.http.HttpServletResponse サーブレット・コンテナー上で JAX-RS アプリケーションが稼動
する場合には HttpServletResponse を取得することができます。
下記に、@PathParam、@MatixParam、@QueryParam と、取得する情報は重複しますが@Context と
UriInfo を使用して、リクエスト URI のパス情報、マトリックス・パラメータ、クエリー・パラメータ値を取得す
る例を示します。
例 4-19 HTTP リクエスト情報を取得するサンプル・コード
package com.ise.rsguide.resource;
import java.util.List;
import java.util.Map.Entry;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
- 42 -
import javax.ws.rs.MatrixParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.UriInfo;
@Path("param/test")
public class ParamTestResource {
public ParamTestResource(){};
@GET
@Path("{path1}/{path2}")
public String getPrm(
@PathParam("path1") String path1,
@PathParam("path2") String path2,
@MatrixParam("mpara1") String mpara1,
@MatrixParam("mpara2") String mpara2,
@QueryParam("qpara1") String qpara1,
@QueryParam("qpara2") String qpara2,
@Context UriInfo uriInfo
){
System.out.println("# path1 =["+path1+"] #");
System.out.println("# path2 =["+path2+"] #");
System.out.println("# mpara1 =["+mpara1+"] #");
System.out.println("# mpara2 =["+mpara2+"] #");
System.out.println("# qpara1 =["+qpara1+"] #");
System.out.println("# qpara2 =["+qpara2+"] #");
System.out.println("# uriInfo.getPath() =["+uriInfo.getPath()+"] #");
System.out.println("# PathParameters #");
for(Entry<String, List<String>> ent :uriInfo.getPathParameters().entrySet()){
System.out.println(entry.getKey()+" : "+ent.getValue());
}
- 43 -
System.out.println("# QueryParameters #");
for(Entry<String, List<String>> ent :uriInfo.getQueryParameters().entrySet()){
System.out.println(entry.getKey()+" : "+ent.getValue());
}
System.out.println("# PathSegment #");
for(PathSegment ps :uriInfo.getPathSegments()){
System.out.println(ps.getPath()+" : "+ps.getMatrixParameters());
}
…
}
}
下記の URI を使用してアクセスすると、SystemOut に、各パラメーターの値が記録されます。
アクセス URI
http://<hostname>:<port>/Web20FPGuide/jaxrs/param/test/parent/child;mpara1=m1;mpara2=m2?qpara1
=q1&qpara2=q2
例 4-20 SystemOut の出力例
# path1 =[parent] #
# path2 =[child] #
# mpara1 =[m1] #
# mpara2 =[m2] #
# qpara1 =[q1] #
# qpara2 =[q2] #
# uriInfo.getPath() =[param/test/parent/child;mpara1=m1;mpara2=m2] #
# PathParameters #
path1 : [parent]
path2 : [child]
# QueryParameters #
qpara1 : [q1]
qpara2 : [q2]
# PathSegment #
param : []
test : []
parent : []
child : [mpara1=m1,mpara2=m2]
上記のコード例のように、@PathParam や@QueryParam などのアノテーションを使用する場合は、アノ
テーションの値(暗黙的な value 属性の値)として、キーとなる値を指定する必要があります。インジェクトさ
れる変数は、必ずしも、String 型である必要はありませんが、プリミティブ型か String から変換可能なオブ
- 44 -
ジェクト(String を引数に取るコンストラクターを持つオブジェクトなど)である必要があります。詳細は、
JAX-RS API Document を参照ください。また、HTTP リクエスト情報の取得については、下記の
Information Center の記載も参考にしてください。
•
Web 2.0 FP Information Center 「RESTful アプリケーションにおけるリソース要求の表
現に関するパラメーターの定義」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.web
20fepjaxrs.doc/info/ae/ae/twbs_jaxrs_defresource_parmexchdata.html
4-3-4 レスポンス HTTP ヘッダーの設定
「4-3-2 エンティティー・ボディーの取得/生成」において、JAX-RS でのレスポンス・ボディーの生成方
法について説明しました。RESTful アプリケーションにおいては、HTTP ステータスコードなどの HTTP
ヘッダーについても、注意して、設計/実装する必要があります。この節では、REST 応答における HTTP
ヘッダーの操作について説明します。
リソース・メソッドでの処理が正常に完了した場合の JAX-RS のデフォルトの HTTP ステータスコード
は、エンティティー・ボディーの有無によって異なり下記の表のようになります。
表 4-9 JAX-RS におけるデフォルトの HTTP ステータスコード
レスポンスのエン デ フ ォ ル ト の ステータスコー 備考
ティティー・ボデ HTTP ステー ドの意味
ィーの有無
タスコード
有
200
OK
リソース・メソッドの戻り値が void ではない場合。
一般に、GET メソッドの応答など。
無
204
No Content
リソース・メソッドの戻り値が void の場合。
一般に、DELETE メソッドの応答など。
リソース・メソッドの応答の HTTP ヘッダーを操作するには、javax.ws.rs.core.Response クラスを使用しま
す。この Response クラスを使用することで、容易に HTTP ヘッダーを制御することができます。Response
クラスは、ビルダー・パターンに基づいて定義された abstract クラスです。
Response クラスのインスタンスは下記の手順で作成します。
1). エンティティー・ボディーのデータを表す Java オブジェクトを作成(「4-3-2 エンティティー・ボディ
ーの取得/生成」を参照ください)
2). Response クラスの static なヘルパー・メソッド(ok(), ok(Object entity), ok(Object entity,
MediaType type), status(int status)など)を使用して、ResponseBuilder のインスタンスを作成
(ResponseBuilder クラスは Response クラスの内部クラスです)
3). ResponseBuilder イ ン ス タ ン ス の メ ソ ッ ド (entity(Object entity), status(int status),
type(MediaType type), language(Locale language), header(String name, Object value)な
ど)を呼び出して、レスポンス HTTP ヘッダーを設定
4). ResponseBuilder インスタンスの build()メソッドを呼び出し、Response クラスのインスタンスを
生成
「4-3-2-2 XML コンテンツの送受信」の例を修正し、HTTP ステータスコードを 200 OK、Content-Type
ヘッダーの値として「application/xml」と、独自の HTTP ヘッダーとして、”MyHeader”と値”my header
value”を追加した場合の例は下記のようになります。
- 45 -
例 4-21 Response オブジェクトを使用したサンプル・コード
package com.ise.rsguide.resource;
import java.util.List;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.ise.rsguide.jaxb.*;
@Path("team")
public class TeamResource {
public TeamResource(){};
@Path("players")
@GET
@Produces("application/xml")
public Response listXMLPlayers2(){
Team team = new Team();
List<Player> playersList = team.getPlayer();
Player player1 = new Player("阿部","MF","2");
Player player2 = new Player("田中","DF","4");
playersList.add(player1);
playersList.add(player2);
ResponseBuilder builder = Response.ok(team);
builder.type(MediaType.APPLICATION_XML_TYPE)
.header("MyHeader", "my header value");
return builder.build();
}
}
また、このリソース・メソッドを呼び出した場合の HTTP 応答は下記のようになります。Content-Type ヘ
ッダーの値として”application/xml”、独自に追加した”MyHeader”のヘッダーとその値として、”my header
- 46 -
value”が追加されていることが確認できます(見易さのため、エンティティー・ボディーの内容は一部改行
を追加しています)。
例 4-22 Response オブジェクトを使用したサンプル・コードにアクセスした HTTP レスポンス
HTTP/1.1 200 OK
Content-Type: application/xml
MyHeader: my header value
Content-Language: ja-JP
Content-Length: 200
Date: Sat, 28 Aug 2010 02:53:50 GMT
Server: WebSphere Application Server/7.0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<team>
<player id="2"><name>阿部</name><position>MF</position></player>
<player id="4"><name>田中</name><position>DF</position></player>
</team>
Response.ResponseBuilder クラスには、type メソッドだけでなく、他にもさまざまな HTTP ヘッダーを設
定するメソッドが準備されています。詳細は JAX-RS API ドキュメントを参照ください。
上記の例では、200 OK の正常 HTTP 応答を返していますが、下記の例のように、200 OK 以外の応
答を返すこともできます。下記の例では、URI に指定される id の値に応じて、id が 24 以上の場合には、
404 Not Found のステータスコードを応答します。
例 4-23 200 OK 以外のステータスコードを返すサンプル・コード
@Path("players/{id}")
@GET
@Consume("application/xml ")
@Produces("application/xml,text/plain")
public Response getPlayer(@PathParam("id") int id){
if(id <= 23){
Player player = new Player(id);
return Response.ok(player)
.type(MediaType.APPLICATION_XML_TYPE).build();
}else{
return Response.status(Status.NOT_FOUND)
.entity("24 番以降の選手は存在しません。")
.type(MediaType.TEXT_PLAIN_TYPE).build();
}
}
- 47 -
5 RESTful Web サービス・クライアン
トの開発
この章では、RESTful Web サービスを呼び出すクライアントの作成方法について、説明します。
5-1 Dojo Toolkit による HTTP 送信
Dojo Toolkit は、JavaScript Toolkit の 1 つで、Web 2.0 FP に含まれています。同梱されているバージョ
ンは 1.4 です。Dojo Toolkit を利用するには、以下の手順を実行します。
1). プロジェクトを選択し、Alt+Enter を押す(もしくは、プロジェクトを右クリック > プロパティー > プ
ロジェクト・ファセット)。
2). Web2.0 > Dojo Toolkit にチェックを入れ、"OK"をクリック。
プロジェクトの WebContent 以下に、dojo ディレクトリーが作成されていれば、利用可能な状態になっ
ています。Dojo ライブラリーを、Web ページ内で利用するためには、Web ページ内(通常、HEAD タグ
内)に、以下の記述を追加します。
例 5-1 Dojo ライブラリーの宣言
<script type="text/javascript" src="/dojo/dojo/dojo.js" djConfig="parseOnLoad: true"></script>
また、Dijit パーツを利用するには、以下の記述を追加し、パーツを配置するタグの上位に位置するタ
グ(通常、body タグ)に class 要素を追加します。
例 5-2 Dijit パーツの宣言
<link href="/dojo/dojo/resources/dojo.css" rel="stylesheet" type="text/css">
<link href="/dojo/dijit/themes/{theme}/{theme}.css" rel="stylesheet" type="text/css">
<body class="{theme}">
上の例で、{theme}と書かれている部分には、tundra、soria、nihilo の 3 種類がデフォルトで選べます。
具体例については、サンプル・アプリケーションの記述をご覧ください。
5-1-1 dojo.xhr
dojo.xhr は、HTTP リクエストを送るためのメソッドです。下記のように利用します。
例 5-3 dojo.xhr のコード・サンプル
dojo.xhr("GET", {
url:"jaxrs/employees?dept="+item.id,
- 48 -
handleAs:"json",
load: function(data,ioargs){
console.log(data);
},
error: function(error,ioargs) {
console.warn(error);
if (ioargs.xhr.status == 404) {
// HTTP ステータスコードが 404 の時の処理を記述
} else if (ioargs.xhr.status == 400) {
// HTTP ステータスコードが 400 の時の処理を記述
} else {
// その他のコードが返ってきた際の処理を記述
}
}
});
上 記 の 例 で は 、 HTTP GET リ ク エ ス ト を 、 jaxrs/employees に 対 し て 、 ク エ リ ー ・ パ ラ メ ー タ
dept=${item.id}を送信し、結果を JSON でパースしてオブジェクトにし、成功した場合はログをコンソー
ルに出力し、失敗した場合は警告をコンソールに出力します。パラメーターの詳細等については、参考
文献の Dojo API Reference と、DojoCampus をご覧ください。
この処理を、画面のイベントのイベント・ハンドラーとして登録しておけば、イベント発生時に、HTTP リ
クエストを送信させることができます。イベントを登録する対象の取得には、dojo.byId 関数や dijit.byId 関
数、イベント・ハンドラーの登録には、dojo.connect 関数が利用できます。
例 5-4 dojo.byId 関数のサンプル・コード
dojo.connect(dojo.byId("mybutton"), "onClick", function() {
dojo.xhr("GET", {
........
});
}
5-1-2 dojo.data.ItemFileReadStore
dojo.data.ItemFileReadStore は、データストアと呼ばれる dojo のクラスです。データストアは、ツリー表
示やグリッド表示など、様々な Dojo の画面パーツと連携できるように設計されています。また、各種の処
理を行うためのメソッドが用意されているため、データの格納先として利用するのにも便利です。このクラ
スと、このクラスを継承した各種のデータストアのクラスは、データの取得対象に URL を指定すると、指
定された URL に対して HTTP リクエストを送信します。
ただし、この指定した URL が返すべきデータの構造は決まっており、それ以外の形式を受け取ること
ができません。データストアは、以下の形式のデータ・フォーマットを要求します。
例 5-5 dojo.data.ItemFileReadStore の形式
[
identifier : "{id}"
label : "{label}"
- 49 -
items : [
{ ...... },
{ ...... },
......
{ ...... }
]
]
{id}と{label}には、items に含まれるデータ項目名が入ります。id は必須で、items を特定できる一意
な値を持つデータ項目でなければなりません。label はオプション値で、各種の画面パーツで実際に表
示される名前が入っているデータ項目を指定します。items には、データが入ります。
これ以外の形式を返す RESTful Web サービスである場合は、一度 dojo.xhr によって結果を受け取っ
た後、データを JavaScirpt によって、下記の形式に変換する必要があります。詳細については、次の節
を参照してください。
Dijit パーツは、マークアップによる生成と、JavaScript による生成の両方をサポートしています。具体
的には、下記のように、オブジェクトを作成します。
例 5-6 マークアップによる生成
<span dojoType="dojo.data.ItemFileReadStore" jsId="emp_store" url="jaxrs/employees"
urlPreventCache="true" clearOnClose="true"></span>
例 5-7 JavaScript による生成
var store = new dojo.data.ItemFileReadStore({
jsId: "emp_store",
url: "jaxrs/employees",
urlPreventCache: "true",
clearOnClose="true"
});
上記の 2 種類の宣言は全く同等のものです。ただし、マークアップによる宣言は HTML がレンダリン
グされた際に解釈されるため、レンダリング後に、マークアップ形式の HTML を JavaScript で追加して
も、Dijit パーツとして認識されませんので注意してください(dojo.parser を利用する必要があります)。パ
ラメーターの詳細等については、参考文献の Dojo API Reference と、DojoCampus をご覧ください。
5-1-3 dojo.xhr と DataStore の連携
データストアは、URL 以外にも、data プロパティーによる生成も可能です。上記のデータ・フォーマット
を返す Web サービスではない場合、dojo.xhr を利用してデータを取得し、データを加工して上記のデー
タ・フォーマットに変換した後に、data プロパティーを利用してオブジェクトを生成します。
例えば、レコードの単純な配列を返す RESTful Web サービスが対象となる場合は、以下のように記述
します。
例 5-8 data プロパティーにようデータストアの生成
dojo.xhr("GET", {
url:"jaxrs/employees?dept="+item.id,
handleAs:"json",
load: function(data,ioargs){
- 50 -
var data_obj = {identifier : "id", label : "name", items : data};
var store = new dojo.data.ItemFileReadStore({data : data_obj});
},
error: function(error,ioargs) {
console.warn(error);
}
});
data_obj オブジェクトを新規作成し、そのプロパティーとして、dojo.xhr の結果が格納されている data
オブジェクトを指定しています。これを dojo.data.ItemFileReadStore の data プロパティーに与えることで、
データストアを新規作成することができます。identifier と label は、JavaScript 内に文字列として記述して
います。
5-2 Java による HTTP 送信
Java の HTTP ライブラリーには様々なものがあります。これらを利用して、HTTP リクエストを送信し、処
理する方法を説明します。
5-2-1 java.net.URL
Java 標準のクラスで、HTTP に限らない、様々なプロトコルの送信を行うことができます。ライブラリーに
依存しないコードを書くことができる点はメリットですが、原始的なメソッドしか提供されていないため、処
理を記述するのはやや煩雑です。
5-2-1-1 HTTP GET の送信
java.net.URL によって、HTTP GET を送信する例を以下に示します。
例 5-9 com.ibm.myfirstrestclient.SampleOfURL_GET クラス
package com.ibm.myfirstrestclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import com.ibm.json.java.JSON;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;
public class SampleOfURL_GET {
- 51 -
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
System.out.println("executing request " + url.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Operation failed. \n -HTTP Status Code : "
+conn.getResponseCode()+"\n -HTTP Entity Body : "+conn.getResponseMessage());
}
System.out.println("Content-Type : "+conn.getContentType());
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String body = "";
String line = "";
while ((line = br.readLine()) != null) {
body += line;
}
conn.disconnect();
System.out.println("Entity Body (As String) : "+body);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
結果は以下のように出力されます。
例 5-10 実行結果(例 5-9)
executing request http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees
Content-Type : application/json
Entity Body (As String) : {"items":[{"emp_id":"857014","dept":"1","name":"Ichiro Tanaka"},{"em
p_id":"429153","dept":"2","name":"Taro Suzuki"},{"emp_id":"143487","dept":"7","name":"Jiro Yam
ada"}],"label":"name_j","identifier":"emp_id"}
5-2-1-2 HTTP POST の送信
java.net.URL によって、HTTP POST を送信する例を以下に示します。
例 5-11 com.ibm.myfirstrestclient.SampleOfURL_POST クラス
package com.ibm.myfirstrestclient;
- 52 -
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class SampleOfURL_POST {
public static void main(String[] args) {
try {
URL url = new URL("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
OutputStream os = conn.getOutputStream();
os.write("{id:'1'}".getBytes());
os.flush();
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Operation failed. \n -HTTP Status Code : "
+conn.getResponseCode()+" "+conn.getResponseMessage());
}
System.out.println("Operation successful done.");
System.out.println("
-HTTP Status Code : "+conn.getResponseCode()+" "
+conn.getResponseMessage());
System.out.println("
-Content-Type
: "+conn.getHeaderField("Content-Type"));
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String body = "";
String line = "";
while ((line = br.readLine()) != null) {
body += line;
}
System.out.println("
-Entity-Body
: "+body);
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
- 53 -
}
}
}
結果は以下のように出力されます。
例 5-12 実行結果(例 5-11)
Operation successful done.
-HTTP Status Code : 200 OK
-Content-Type
: text/plain;charset=UTF-8
-Entity-Body
: onCreate()が呼び出されました。 -> {id:'1'}
5-2-2 Apache HttpClient
Apache HttpClient は、2001 年に Jakarta Commons のサブプロジェクトとして開始したプロジェクトの 1
つで、現在は Apache プロジェクトとして開発が継続されています。公式サイトはこちらです。
http://hc.apache.org/httpcomponents-client/index.html
2010 年 8 月現在の最新版は 4.0 です。ただし、WAS の Web App ライブラリーに含まれるライブラリー
のバージョンは 3.1 となっており、間もなく非推奨となる予定ですので、利用する場合は最新版のモジュ
ールを利用することを推奨します。
Apache HttpClient を利用すると、java.net.URL を利用するよりも効率よく HTTP 送信処理を記述する
ことができます。ただし、WebDAV 仕様は実装されておらず、クラス間の関係から、WebDAV で定義され
た HTTP メソッドを送信するのは困難になっています。
5-2-2-1 HTTP GET の送信
Apache HttpClient によって、HTTP GET を送信する例を以下に示します。
例 5-13 com.ibm.myfirstrestclient.SampleOfApacheHttpClient_GET クラス
package com.ibm.myfirstrestclient;
import java.io.IOException;
import java.util.Iterator;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import com.ibm.json.java.JSON;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;
public class SampleOfApacheHttpClient_GET {
public static void main(String[] args) {
- 54 -
try {
HttpClient httpclient = new HttpClient();
GetMethod method
= new GetMethod("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
System.out.println("executing request " + method.getURI());
int status = httpclient.executeMethod(method);
if (status != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
System.out.print(method.getResponseHeader("Content-Type").toString());
String responseBody = new String(method.getResponseBody());
System.out.println("Entity Body (As String) : "+responseBody);
} catch (IOException e) {
e.printStackTrace();
}
}
}
結果は以下のように出力されます。
例 5-14 実行結果(例 5-13)
executing request http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees
Content-Type: application/json;charset=UTF-8
Entity Body (As String) : {"items":[{"emp_id":"857014","dept":"1","name":"Ichiro Tanaka"},{"em
p_id":"429153","dept":"2","name":"Taro Suzuki"},{"emp_id":"143487","dept":"7","name":"Jiro Yam
ada"}],"label":"name_j","identifier":"emp_id"}
5-2-2-2 HTTP POST の送信
Apache HttpClient によって、HTTP POST を送信する例を以下に示します。
例 5-15 com.ibm.myfirstrestclient.SampleOfApacheHttpClient_POST クラス
package com.ibm.myfirstrestclient;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
public class SampleOfApacheHttpClient_POST {
public static void main(String[] args) {
try {
- 55 -
HttpClient httpclient = new HttpClient();
PostMethod method
= new PostMethod("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
System.out.println("executing request " + method.getURI());
RequestEntity requestEntity
= new StringRequestEntity("{id:'1'}", "application/json", "UTF-8");
method.setRequestEntity(requestEntity);
int status = httpclient.executeMethod(method);
if (status != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
}
System.out.println("Operation successful done.");
System.out.println("
-HTTP Status Code : "+method.getStatusCode()+" "
+method.getStatusText());
System.out.print("
-Content-Type
System.out.println("
-Entity-Body
: "+method.getResponseHeader("Content-Type"));
: "+method.getResponseBodyAsString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
結果は以下のように出力されます。
例 5-16 実行結果(例 5-15)
executing request http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees
Operation successful done.
-HTTP Status Code : 200 OK
-Content-Type
: Content-Type: text/plain;charset=UTF-8
-Entity-Body
: onCreate()が呼び出されました。 -> {id:'1'}
5-2-3 Apache Wink
Web 2.0 FP に含まれる Apache Wink は RESTful Web サービスを作るためのフレームワークで、サー
バー側と、クライアント側と、両方のライブラリーを提供しています。公式サイトはこちらです。
http://incubator.apache.org/wink/
サーバー側のモジュールは、JAX-RS が実装されており、WAS の JAX-RS 実装もこちらを利用してい
ます。クライアント側のモジュールは、RESTful Web サービスとの通信を考慮したライブラリーになってお
り、Apache HttpClient よりも柔軟に、効率よく RESTful Web サービスをコールすることができます。また、
WebDAV によって定義された HTTP メソッドも送信することが比較的容易になっています。
5-2-3-1 HTTP GET の送信
Apache Wink によって、HTTP GET を送信する例を以下に示します。
- 56 -
例 5-17 com.ibm.myfirstrestclient.SampleOfApacheWink_GET クラス
package com.ibm.myfirstrestclient;
import java.io.IOException;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
import com.ibm.json.java.JSONObject;
public class SampleOfApacheWink_GET {
public static void main(String[] args) {
try {
RestClient client = new RestClient();
Resource resource
= client.resource("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
JSONObject response = resource.accept("application/json").get(JSONObject.class);
System.out.println(response.serialize(true));
} catch (IOException e) {
e.printStackTrace();
}
}
}
結果は以下のように出力されます。
例 5-18 実行結果(例 5-17)
{
"identifier": "emp_id",
"items": [
{
"dept": "1",
"emp_id": "857014",
"name": "Ichiro Tanaka"
},
{
"dept": "2",
"emp_id": "429153",
"name": "Taro Suzuki"
},
{
"dept": "7",
"emp_id": "143487",
- 57 -
"name": "Jiro Yamada"
}
],
"label": "name_j"
}
5-2-3-2 HTTP POST の送信
Apache Wink によって、HTTP POST を送信する例を以下に示します。
例 5-19 com.ibm.myfirstrestclient.SampleOfApacheWink_POST クラス
package com.ibm.myfirstrestclient;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
public class SampleOfApacheWink_POST {
public static void main(String[] args) {
RestClient client = new RestClient();
Resource resource
= client.resource("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
ClientResponse response = resource.contentType("application/json").post("{id:'1'}");
System.out.println("Operation successful done.");
System.out.println("
-HTTP Status Code : "+response.getStatusCode()+" "
+response.getMessage());
System.out.println("
-Content-Type
: "
+response.getHeaders().get("Content-Type").get(0));
System.out.println("
-Entity-Body
: "+response.getEntity(String.class));
}
}
結果は以下のように出力されます。
例 5-20 実行結果(例 5-19)
Operation successful done.
-HTTP Status Code : 200 OK
-Content-Type
: text/plain;charset=UTF-8
-Entity-Body
: onCreate()が呼び出されました。 -> {id:'1'}
- 58 -
5-2-3-3 Basic 認証
Apache Wink によって、Basic 認証を伴った HTTP GET を送信する例を以下に示します。特にメソッド
が提供されているわけではないので、Base64 エンコードを行った上で、Authorization ヘッダーにその値
を付与しています。結果は通常の HTTP GET と同一ですので省略します。
例 5-21 com.ibm.myfirstrestclient.SampleOfApacheWink_GET_Auth クラス
package com.ibm.myfirstrestclient;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
import com.ibm.misc.BASE64Encoder;
public class SampleOfApacheWink_GET_Auth {
public static void main(String[] args) {
RestClient client = new RestClient();
Resource resource
= client.resource("http://localhost:9080/MyFirstRESTServiceWeb/jaxrs/employees");
String logon = "admin:admin";
String encodedLogon = new BASE64Encoder().encode(logon.getBytes());
resource.header("Authorization", "Basic " + encodedLogon);
JSONObject response = resource.accept("application/json").get(JSONObject.class);
System.out.println(response.serialize(true));
}
}
- 59 -
参考資料
JAX-RS 1.0/1.1 仕様
http://jcp.org/en/jsr/summary?id=311
IBM WebSphere「WebSphere Application Server Feature Pack for Web 2.0」
http://www-01.ibm.com/software/webservers/appserv/was/featurepacks/web20/
Web 2.0 FP Information Center「IBM JAX-RS の概要」
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.nd.d
oc/info/welcome_nd.html
Apache Wink
https://cwiki.apache.org/WINK/index.html
書籍:Bill Burke 著(2009) 「RESTful Java with JAX-RS」 O’REILLY
書籍:Leonard Rechardson, Sam Ruby 著, 山本陽平 監訳, 株式会社クイープ訳(2007)
「RESTful Web サービス」 オライリー・ジャパン
書籍:山本陽平 著(2010) 「Web を支える技術」 技術評論社
DeveloperWorks「Create RESTful Web services with Java technology」
http://www.ibm.com/developerworks/web/library/wa-jaxrs/
Dojo Toolkit
http://dojotoolkit.org/
Dojo API Reference
http://dojotoolkit.org/api/
Dojo Campus
http://dojocampus.org/explorer/
- 60 -
Fly UP