• 検索結果がありません。

JAX-RS 2.1 Reactive REST クライアント実行

ドキュメント内 Java Day Tokyo 2017 ダウンロード資料 (ページ 34-59)

ハンズオン概要

 本ハンズオンで参照するコードは以下の GitHub 上にアップされたコー ドです。(git tag: beforehandson)

https://github.com/nobuhikosekiya/jaxrs21handson/tree/beforehand son

 ハンズオンを完了したときの状態のコードは以下の URL にありますの で、必要に応じて参考にしてください。(git tag: afterhandson) https://github.com/nobuhikosekiya/jaxrs21handson/tree/afterhands on

 これらのハンズオンのコードは、下記 URL にある JAX-RS のリファレン ス実装である Jersey の GitHub リポジトリ上のサンプルコードをベース にしており、本ハンズオン向けに一部コードを省略しています。

https://github.com/jersey/jersey/tree/2.26-b02/examples/rx-client-webapp

(今回の GlassFish に含まれている Jersey と同じバージョンのタグ番 号 2.26-b02 のサンプルを使います)

アプリケーション構成について

35

ハンズオンプロジェクトの作成

新たにこれ以降のハンズオン用の新規の NetBeans プロジェクトを作成します。

メニューから「ファイル (F)」→「新規プロジェクト(W)...」を選択してくだ さい。

表示される下記ウィンドウのカテゴリから「Java Web」を選択し、さらにプロ ジェクトから「Web アプリケーション」を選択し、「次 >」を押してくださ い。

次に表示される下記ウィンドウの「プロジェクト名」をここでは

「JavaEE8-JaxRS」として設定します。前回のプロジェクトと同様に、

ライブラリ・フォルダを今回インストールした GlassFish 5 内の lib

フォルダを指定し、「次 > 」を押してください。

次に表示される下記ウィンドウの「サーバー」は前回のプロジェクト で作成した「GlassFish 5 EA」が設定されていることを確認します。

コンテキスト・パスは、URL パスを簡単にするために今回は

「/jaxrs21」とし、「次 > 」を押してください。

37

プロジェクトへのライブラリの追加

この章のハンズオンで利用するライブラリは以下の通りです。

 RxJava … 今回のハンズオンで利用するリアクティブプログラミ ングのフレームワーク

 Jersey Reactive Client- RXJava provider … JAX-RS の Reactive Client で RxJava を利用するための拡張

 jersey-server.jar と jersey-guava.jar …今回のプロジェクトの REST サーバー側の実装に使用しているライブラリです。 JAX-RS Reactive Client とは直接は関係ありません。

今回のハンズオンで利用する RxJava(バージョン 1)のライブラリ JAR ファイルを以下のサイトよりダウンロードして、自身の PC の任意 のフォルダに保存してください。

https://mvnrepository.com/artifact/io.reactivex/rxjava/1.2.5

さらに、JAX-RS の Reactive REST クライアントから RxJava を組み込 むための JAX-RS の拡張実装のライブラリ(Jersey Reactive Client- RXJava provider)もダウンロードしてください。

https://mvnrepository.com/artifact/org.glassfish.jersey.ext.rx/jersey-rx-client-rxjava/2.26-b02

※RxJava と拡張ライブラリのバージョンの組み合わせ( rxjava 1.25 と jersey-rx-client-rxjava 2.26-b02)は、必ずここで指定したもの を本ハンズオンでは使用してください。組み合わせバージョンが異な ると、プロジェクトのコンパイルでエラーとなる場合があります。

以降の手順で、ダウンロードしたライブラリをプロジェクトで利用で

きるように設定します。

39 ->

表示される下記ウィンドウのカテゴリの「ソース」では、ソースバイ ナリ形式が「JDK8」に設定されていることをまず確認してください。

次に、カテゴリから「ライブラリ」を選択し、「ライブラリの追加」

ボタンを押してください。

次に表示されるウィンドウで「作成」ボタンを押し、ライブラリ名と

して「rxjava」と入力して「OK」を押してください。

「JAR/フォルダの追加」を押してください。

さきほどダウンロードした「rxjava-1.2.5.jar」を選択して「JAR/フ

ォルダの追加」ボタンを押してください。

41

以下のようなダイアログが表示されますので「はい」を押してくださ い。

その後、もう一つの jar ファイル「jersey-rx-client-rxjava-2.26-b02.jar」を選択して同様に追加してください。

その後、戻った下記ウィンドウの「OK」ボタンを押してください。

OK ボタン後に下記のウィンドウに戻るので、先ほど追加したライブラ

リを選択した状態で「ライブラリの追加」を押してください。

43

「作成」ボタンを押し、ライブラリ名を「jersey-libs」とし、「OK」

を押してください。

「JAR/ライブラリの追加」ボタンを押してください。

今回は glassfish/modules フォルダ(lib フォルダと同階層のフォル ダです)にある jersey-guava.jar と jersey-server.jar を追加してく ださい。

以下のように、2つの jar を設定したら、「OK」ボタンを押してくだ

さい。

45

OK 押し後に戻ったウィンドウでは、さきほど作成した「jersey-libs」を選択した上で「ライブラリの追加」ボタンを押してくださ い。

以下のように2つのライブラリ(中には計 4 つの jar ファイル)が登

録されたら「OK」を押して、ライブラリの登録は終了となります。

REST

サーバーの作成

以下の GitHub の URL より今回のハンズオンのサンプルコードをダウンロードし てください。

https://github.com/nobuhikosekiya/jaxrs21handson/archive/beforehandson.zip ダウンロードした zip ファイルを任意の場所に解凍し、中に含まれる src\java のディレクトリ配下の org フォルダをプロジェクトのソース・パッケージへコ ピーペーストしてください。

->

その後、プロジェクトを右クリックし、「デプロイ」を実行してください。

47

デプロイが成功したのち、以下の URL をブラウザのアドレスバーに入力し、

JSON 形式のデータが返ってくることを確認してください。

※実際のブラウザ画面での JSON 文字列は整形されていません。以降も本ドキュ メント内では見やすいように結果は整形している場合があります。

http://localhost:8080/jaxrs21/rx/remote/destination/visited

[ {

"destination": "Zambia"

}, {

"destination": "Kiribati"

}, {

"destination": "Japan"

}, {

"destination": "Saudi Arabia"

}, {

"destination": "Palau"

} ]

http://localhost:8080/jaxrs21/rx/remote/destination/recommended

[ {

"destination": "Greece"

}, {

"destination": "Malta"

}, {

"destination": "Benin"

}, {

"destination": "Sweden"

}, {

"destination": "Uganda"

} ]

http://localhost:8080/jaxrs21/rx/remote/forecast/Tokyo

<forecast>

<destination>

Tokyo </destination>

</forecast>

<forecast>

Partly Sunny

</forecast>

http://localhost:8080/jaxrs21/rx/remote/calculation/from/Moon/to/Tokyo

<calculation>

<from>

Moon </from>

<price>

1680 </price>

<to>

Tokyo </to>

</calculation>

JAX-RS sync client

の作成

リアクティブな JAX-RS クライアントとの対比のために最初にベーシックな同期 型の JAX-RS クライアントを作成します。

プロジェクトを右クリックし、新規の Java パッケージを作成してください。パ ッケージ名は「org.glassfish.jersey.examples.rx.agent」とします。

次に、作成したパッケージ「org.glassfish.jersey.examples.rx.agent」を右

クリックし、新規の Java クラスを作成してください。

49

クラス名に「SyncAgentResource」と入力し、「終了」ボタンを押してくださ い。

クラス作成後、以下の赤字の部分のコードを追加してください。

package org.glassfish.jersey.examples.rx.agent;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import org.glassfish.jersey.examples.rx.domain.AgentResponse;

@Path("agent/sync")

@Produces("application/json") public class SyncAgentResource { @GET

public AgentResponse sync() {

final long time = System.nanoTime();

final AgentResponse response = new AgentResponse();

response.setProcessingTime((System.nanoTime() - time) / 1000000);

return response;

} }

コード変更を保存すると、自動的に変更がデプロイされます。以下の URL にブ ラウザからアクセスし、現段階の実行結果を確認してください。ここでは単に 空の AgentResponse のオブジェクトを JSON として返却しているだけです。

http://localhost:8080/jaxrs21/rx/agent/sync 実行結果の例

{"processingTime":0,"visited":[]}

次に、以下の赤字のコードを先ほどの SyncAgentResource クラスのソースに追 加で挿入してください。

import java.util.List;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import org.glassfish.jersey.examples.rx.domain.AgentResponse;

import javax.ws.rs.client.Client;

import javax.ws.rs.client.ClientBuilder;

import javax.ws.rs.client.WebTarget;

import javax.ws.rs.core.GenericType;

import org.glassfish.jersey.examples.rx.domain.Destination;

(省略)

public class SyncAgentResource {

final private Client client = ClientBuilder.newClient();

final private WebTarget destination =

client.target("http://localhost:8080/jaxrs21/rx").path("remote/destination");

@GET

public AgentResponse sync() {

final long time = System.nanoTime();

final AgentResponse response = new AgentResponse();

final List<Destination> visited = destination.path("visited").request() // Identify the user.

.header("Rx-User", "Sync") // Return a list of destinations

.get(new GenericType<List<Destination>>() {});

response.setVisited(visited);

(省略)

コードの保存により変更がデプロイされるので、以下の URL の実行結果を確認 してください。REST サーバーから Destination の情報を取得できるようになり ました。

http://localhost:8080/jaxrs21/rx/agent/sync 実行結果の例

{"processingTime":548,"visited":[{"destination":"Botswana"},{"destina tion":"Spain"},{"destination":"Lesotho"},{"destination":"Iceland"},{"

destination":"Venezuela"}]}

次に、以下の赤字のコードを同じクラスに追加してください。Recommend のデ ータを REST サーバーより取得するコードです。

(省略)

response.setVisited(visited);

51

response.setProcessingTime((System.nanoTime() - time) / 1000000);

(省略)

そのまま次に、以下の赤字のコードを挿入してください。Recommend の

destintion データ毎に forecast データを REST サーバーに繰り返し問い合わせ ています。

import org.glassfish.jersey.examples.rx.domain.Forecast;

import java.util.ArrayList;

final private WebTarget destination =

client.target("http://localhost:8080/jaxrs21/rx").path("remote/destination");

final private WebTarget forecast = client.

target("http://localhost:8080/jaxrs21/rx").path ("remote/forecast/{destination}");

(省略)

final List<Destination> recommended = (省略)

// Forecasts. (depend on recommended destinations)

final List<Forecast> forecasts = new ArrayList<>(recommended.size());

for (final Destination dest : recommended) {

forecasts.add(forecast.resolveTemplate("destination", dest.getDestination()).request().get(Forecast.class));

}

response.setProcessingTime((System.nanoTime() - time) / 1000000);

http://localhost:8080/jaxrs21/rx/remote/calculation/from/Moon/to/Morroc o

<calculation><from>Moon</from><price>6482</price><to>Morroco</to></ca lculation>

http://localhost:8080/jaxrs21/rx/remote/calculation/from/Moon/to/Cyprus

<calculation><from>Moon</from><price>8239</price><to>Cyprus</to></cal culation>

そのまま次に、以下の赤字のコードを挿入してください。Recommend の

destintion データ毎に Moon からその destination までのコストを REST サーバ ーに繰り返し問い合わせています。

import org.glassfish.jersey.examples.rx.domain.Calculation;

final private WebTarget destination =

client.target("http://localhost:8080/jaxrs21/rx").path("remote/destination");

final private WebTarget forecast = client.

target("http://localhost:8080/jaxrs21/rx").path ("remote/forecast/{destination}");

final private WebTarget calculation = client.

target("http://localhost:8080/jaxrs21/rx").path ("remote/calculation/from/{from}/to/{to}");

(省略)

final List<Forecast> forecasts = new ArrayList<>(recommended.size());

for (final Destination dest : recommended) {

forecasts.add(forecast.resolveTemplate("destination", dest.getDestination()).request().get(Forecast.class));

}

// Calculations. (depend on recommended destinations)

final List<Calculation> calculations = new ArrayList<>(recommended.size());

for (final Destination dest : recommended) {

calculations.add(calculation.resolveTemplate("from",

"Moon").resolveTemplate("to", dest.getDestination()) .request().get(Calculation.class));

}

response.setProcessingTime((System.nanoTime() - time) / 1000000);

最後に以下のコードを追加し、レスポンスとしてセットしてます。

import org.glassfish.jersey.examples.rx.domain.Recommendation;

(省略)

final List<Calculation> calculations = new ArrayList<>(recommended.size());

for (final Destination dest : recommended) {

calculations.add(calculation.resolveTemplate("from",

"Moon").resolveTemplate("to", dest.getDestination()) .request().get(Calculation.class));

}

// Recommendations.

final List<Recommendation> recommendations = new ArrayList<>(recommended.size());

for (int i = 0; i < recommended.size(); i++) { recommendations.add(new

Recommendation(recommended.get(i).getDestination(), forecasts.get(i).getForecast(),

calculations.get(i).getPrice()));

}

response.setRecommended(recommendations);

response.setProcessingTime((System.nanoTime() - time) / 1000000);

変更をデプロイし、以下の URL の実行結果を確認してください。REST サーバー から Destination の情報を取得できるようになりました。REST サーバーへのリ クエスト回数が何回も行われていることにより、レスポンスが返るまでに時間 がかかっていることがわかります。

http://localhost:8080/jaxrs21/rx/agent/sync 実行結果の例

{

"processingTime": 4700, "recommended": [

{

"destination": "Sao Tome & Principe", "forecast": "Overcast",

"price": 785 },

{

"destination": "China",

"forecast": "Chance of TStorm", "price": 3647

}, {

"destination": "Malta",

ドキュメント内 Java Day Tokyo 2017 ダウンロード資料 (ページ 34-59)

関連したドキュメント