bluemixでgwtアプリケーションを動かす(2)

99
Bluemix で GWT(2) ででででででででででででで

Upload: shisei-hanai

Post on 15-Aug-2015

348 views

Category:

Engineering


6 download

TRANSCRIPT

Page 1: BluemixでGWTアプリケーションを動かす(2)

Bluemix で GWT(2)データベースにアクセスする

Page 2: BluemixでGWTアプリケーションを動かす(2)

概要• 前回に引き続き、 Bluemix で動かす GWT のアプリケーションを完成さ

せます。

• 今回は、前回解説できなかったデータベースアクセスについて取り上げます。

Page 3: BluemixでGWTアプリケーションを動かす(2)

おことわり

• 本資料の記載内容は、私が個人的に調べた内容であり、正式な日本 IBMのテストやレビューを受けておりません。内容について、できる限り正確を期すよう努めてはおりますが、いかなる明示または暗黙の保証も責任も負いかねます。本資料の情報は、使用先の責任において使用されるべきものであることを、あらかじめご了承ください。

Page 4: BluemixでGWTアプリケーションを動かす(2)

前提• 前回の資料について理解していることが前提です。

http://www.slideshare.net/unokichi/bluemixgwt

• 今回は、ごく簡単な機能しか使いませんが、 JavaEE の JPA とCDI 、 EJB の機能について理解していることが前提です。

Page 5: BluemixでGWTアプリケーションを動かす(2)

前回の補足• 前回の資料で、 Bluemix では Java8 が使えないという記載をしましたが、

設定を加えることで、 Java8 も使用できることを、 SlideShare のコメントで blacklead さんから教えていただきました。 cf login した後に、以下を実行するだけで Java8 がデフォルトになります。cf set-env アプリケーション名 JBP_CONFIG_IBMJDK "version: 1.8.+"

• 今回は、 Java8 を使ってみることにします。 PC 側にも Java8 をインストールしておいてください。

Page 6: BluemixでGWTアプリケーションを動かす(2)

Eclipse への Java8 の登録• 最初から Java8 を使用している場合はこの手順はスキップしてください。

• Mac の時は、メニューの Eclipse => 環境設定。それ以外は Window => Preferences を開きます。

Installed JREs を選び

Add を選びます

Page 7: BluemixでGWTアプリケーションを動かす(2)

Java8 の追加

Standard VM を選び

自分が JDK をインストールした場所を指定します。 Mac の場合はインストール場所が分かりにくいですが、 /Library/Java/JavaVirtualMachines/

の下にあるはずです

Page 8: BluemixでGWTアプリケーションを動かす(2)

Java8 の追加

Java8 側にチェックを入れておきます

Page 9: BluemixでGWTアプリケーションを動かす(2)

WebSphere Liberty の導入

Page 10: BluemixでGWTアプリケーションを動かす(2)

WebSphere Liberty profile の導入• GWT デフォルトで導入される Jetty の Embedded mode は、 Servlet

や JSP などの基本機能だけしか使わないのであれば、非常に軽量で手軽である反面、 JavaEE の機能を踏み込んで使おうと思うと、設定やライブラリの追加などで煩雑になり逆に面倒になってきます。

• GWT はアプリケーションサーバに Jetty 以外を使うことも可能なので、今回はアプリケーションに WebSphere Liberty profile( 以後、単にLiberty) を使うことにします。

Page 11: BluemixでGWTアプリケーションを動かす(2)

外部サーバの使用• デフォルトの実行構成

Java プロセス

Jetty(Embedded) port 8888war ディレクトリの下を提供

コードサーバ port 9876

ブラウザ

静的コンテンツサーバーサイドロジッ

開発モードの時に、クライアント側のコード (Java

で書かれたもの ) を実行する

Page 12: BluemixでGWTアプリケーションを動かす(2)

外部サーバの使用• 今回の実行構成

Java プロセス

Liberty port 8888war ディレクトリの下を提供

コードサーバ port 9876

ブラウザ

静的コンテンツサーバーサイドロジッ

開発モードの時に、クライアント側のコード (Java

で書かれたもの ) を実行する

Page 13: BluemixでGWTアプリケーションを動かす(2)

Liberty のインストール

Eclipse で Help => Eclipse Marketplace... を選び、その中から、 IBM WebSphere Application Server Liberty

Profile Developer Tools for Luna( 長っ !) を選んで、 Install をクリックします

インストールが終わると Eclipse の再起動を促されるので再起動しておきます

Page 14: BluemixでGWTアプリケーションを動かす(2)

パースペクティブの切り替え• もしも Servers ビューが無い時は、 JavaEE パースペクティブに切り替

えます。Serves ビュー

画面右上の Java EE パースペクティブ切り替えアイコン。

もしもこのアイコンも無ければ左の + と書かれたアイコンをク

リック

一覧から選択

Page 15: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加Server ビューで、右クリックし、 New => Server を

選びます

Page 16: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

Liberty を選んで、 Next をクリック

Page 17: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

新しく追加する方を選びます

Page 18: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

Libety には、 Web Porfile と Full Platform がありますが、今回は

JavaEE の基本的な機能のみしか使わないので Web Profile を選びます

Page 19: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

そのまま Next

Page 20: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

ライセンス条件を確認して問題なければ Next

Page 21: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

名前の設定必要に応じて変更

Finish をクリック

Page 22: BluemixでGWTアプリケーションを動かす(2)

Liberty の追加

Servers ビューに、 Liberty が追加されるので、その中からHTTP エンドポイントをダブル

クリック

ポートを 9080 から 8888 に変更

Page 23: BluemixでGWTアプリケーションを動かす(2)

DB アクセスのテスト

Page 24: BluemixでGWTアプリケーションを動かす(2)

DB アクセスのテスト• まずは簡単なプログラムで DB アクセスをテストしてみましょう。

• 今回は、 DB サーバとして Postgres を使いますが、 Bluemix 上にサービスとして用意されているので、 PC にはインストールしないで済ますことが可能です。

• Bluemix 上の Postgres には、試験版の postgresql というものと、 ElephantSQL があります。今回は ElephantSQL の方を使用します。

Page 25: BluemixでGWTアプリケーションを動かす(2)

テスト用 DB サーバの構築

カタログからElephantSQL をク

リックします

Page 26: BluemixでGWTアプリケーションを動かす(2)

テスト用 DB サーバの構築

Tiny Turtle ならデータ量20MB 、 5 セッションまでですが、 2015/7 時点では無料

で使用できます

Page 27: BluemixでGWTアプリケーションを動かす(2)

アクセス確認• 今回は、コマンドラインの psql コマンドを用いますが、 GUI 用のツー

ルも大量にありますので、 GUI を使いたい場合はこのあたりから選ぶと良いでしょう。 Eclipse でも基本的なテーブルの内容の編集くらいはできるので、その程度であれば Eclipse 側の機能でも十分です。https://wiki.postgresql.org/wiki/Community_Guide_to_PostgreSQL_GUI_Tools/ja

• psql コマンドは、 Postgres に含まれます。 Postgres のインストールは、Linux や Mac ならパッケージマネージャ (yum, apt-get, brew など ) を使うのが簡単でしょう。 Windows の場合は、以下のページからバイナリが取得できるようです。http://www.postgresql.org/download/windows/

• 今回は、 Mac で以下のコマンドを使ってインストールした、 9.4.0 版を使用します。$ brew install postgresql

Page 28: BluemixでGWTアプリケーションを動かす(2)

Postgres に接続• Bluemix に ElephantSQL を追加すると、アイコンが追加されるので、

ここから開始します。

Page 29: BluemixでGWTアプリケーションを動かす(2)

Postgres に接続

接続情報

Page 30: BluemixでGWTアプリケーションを動かす(2)

Postgres に接続• 以下は、 psql で接続した例です。

$ psql -h jumbo.db.elephantsql.com -U nkxujaob nkxujaob -WPassword for user nkxujaob:psql (9.4.0, server 9.3.6)SSL connection (protocol: TLSv1.2, cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)Type "help" for help.

nkxujaob=> create table messages(message text);CREATE TABLEnkxujaob=> insert into messages (message) values ('Hello');INSERT 0 1nkxujaob=> select * from messages; message--------- Hello(1 row)

nkxujaob=>

パスワードを入力

テーブルを作成し、データを挿入、照会し

ている

パラメータ:-h ホスト名-U ユーザ名データベース名-W パスワードを手入力

Ctrl-D で終了します

Page 31: BluemixでGWTアプリケーションを動かす(2)

アプリケーションからの接続• それでは、前回資料で、 Hello World を作成した要領でアプリケーショ

ンを作成してください (File => New => other => Google =>Web Application Project で、 Use Google App Engine のチェックを外す ) 。今回は dbaccess という名前にしました。

• Liberty にデプロイできるように、ファセットを追加します。 Project Explorer でプロジェクトを右クリックして Properties を選んでファセットを追加します ( 次ページ ) 。

Page 32: BluemixでGWTアプリケーションを動かす(2)

ファセットの追加

Dynamic Web Moduleにチェックを入れて、バージョンを 3.1 に設

JPA にチェックを入れて、バージョンを 2.1 に設

Page 33: BluemixでGWTアプリケーションを動かす(2)

ファセットの追加

プロジェクトが、 Web プロジェクトとして認識され、 EAR プロジェクトが自動的に追加されます

( 今回は、 EAR プロジェクトの方は使いませんので、無視して構いません ) 。

JPA を選択した状態で、右側のペインで、 Runtimes をクリックし、 Liberty のチェック

を入れておく

Page 34: BluemixでGWTアプリケーションを動かす(2)

Web コンテンツディレクトリの設定Eclipse は、デフォルトで WebContent という

ディレクトリを、 Web コンテンツディレクトリとして使いますが、 GWT のウィザードは、 war ディレクトリを使うので、まず WebContent を削除し

ます。

Page 35: BluemixでGWTアプリケーションを動かす(2)

Web コンテンツディレクトリの設定

Add をクリックし、

Folder を選択

Page 36: BluemixでGWTアプリケーションを動かす(2)

Web コンテンツディレクトリの設定

war を選択して Finish をクリックし、/war が追加されたことを確認します

Page 37: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録• Eclipse に登録するため、 JDBC ドライバを入手します。

https://jdbc.postgresql.org/download.html

• 今回はサーバ側が 9.3 なので、 9.3 用の JDBC ドライバを入手します。

Page 38: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録• Eclipse で、 Data Source Explorer ビューを開いて、 Postgres を追加

します。

もしも Data Source Explorer が見つからない時は、 Window => Show View から追加します。

Database Connections を右クリックして、 New を選びます。

Page 39: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録

PostgreSQL を選びます

Page 40: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録最初は、ここは空欄 ここをクリック

Page 41: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録

選択状態にしてからJAR List をクリック

Page 42: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録

選択状態にしてから Remove

Page 43: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録Add でさきほどダウン

ロードした jar を指定します

Page 44: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録

Name/Type に戻り

名前の最後を 8 から9 に変更

OK をクリック

Page 45: BluemixでGWTアプリケーションを動かす(2)

Eclipse に登録

ElephantSQL の接続パラメータを指定

Test Connection をクリックして成功することを確認した

ら、 Finish で終了

Page 46: BluemixでGWTアプリケーションを動かす(2)

テーブルを作成• 今回は、まずテーブルを作成してから、 JPA のエンティティを作成します。

• JPA ではサロゲートキー ( システム的に自動採番されるカラムをプライマリーキーとする ) を使用するのが一般的なので、 psql で以下を実行して、テーブルを作成します。

nkxujaob=> drop table messages;DROP TABLEnkxujaob=> CREATE TABLE messages (id SERIAL not null UNIQUE, message text);CREATE TABLE

psql の動作確認で作成したテーブルを一旦削

Postgres の serial を自動採番カラムとしてテーブルを作成

Page 47: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスを作成• Project Explorer で右クリックして、 JPA Tools => Configure JPA

Entities を選ぶ。

ここをクリック

Page 48: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスを追加

PostgreSQL を選び

messages テーブルを選び

Next をクリック

Page 49: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスを追加

テーブル間関連は今回作らないので、そのまま Next

Page 50: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスを追加

identity を選ぶ

dbaccess.models に変更

Page 51: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスの追加

Finish で完了

Page 52: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスの追加

チェックして

Next

Page 53: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスの追加

Primary Key を選んで

id をチェック

Page 54: BluemixでGWTアプリケーションを動かす(2)

JPA エンティティクラスの追加

作成された Messageをダブルクリックして

これを追加する。これにより Postgresで自動採番された serial が、 id に自動的

に割り当てられる

Page 55: BluemixでGWTアプリケーションを動かす(2)

Liberty へのデプロイ• 作成したプロジェクトを Liberty にデプロイします。

右クリックして、 Add and Remove... を選

びます

左側から dbaccess を選んで、 Add を押して右側に登録されるのを確認します。 EAR の方

は使いません

Page 56: BluemixでGWTアプリケーションを動かす(2)

トランザクション管理• このあと Bluemix にデプロイしますが、その時、データソースは

Bluemix 側で自動的に構成されます。

• 2015/7 時点では、この自動構成されるデータソースは、 XA データソースになるようで、変更する方法は見つかりませんでした。

• XA と非 XA では、プログラミングに差異がどうしても生まれるので、今回はローカル側も XA で動かすことにします。

• 今回選択した Web Profile では、 EJB Lite がサポートされているので、セッションビーンを使ってトランザクション管理をすることにします。

Page 57: BluemixでGWTアプリケーションを動かす(2)

Liberty へのデータソース設定• Liberty の設定を開きます。

Liberty の設定をダブルクリックして、 server.xml を開く

Source タブをクリック

Page 58: BluemixでGWTアプリケーションを動かす(2)

Liberty へのデータソース設定 <webApplication id="dbaccess" location="dbaccess.war" name="dbaccess" contextRoot="/"> </webApplication> <dataSource id='postgresql-mydb' jdbcDriverRef='postgresql-driver' jndiName='jdbc/mydb' transactional='true' type='javax.sql.ConnectionPoolDataSource'> <properties databaseName='nkxujaob' user='nkxujaob' password='xxxxxxxxx' portNumber='5432' serverName='jumbo.db.elephantsql.com'/> </dataSource>

<jdbcDriver id='postgresql-driver' javax.sql.XADataSource='org.postgresql.xa.PGXADataSource' javax.sql.ConnectionPoolDataSource='org.postgresql.ds.PGConnectionPoolDataSource' libraryRef='postgresql-library'/> <library id='postgresql-library'> <fileset id='postgresql-fileset' dir='/Users/shanai/oss/postgres-jdbc' includes='postgresql-9.3-1103.jdbc41.jar'/> </library> </server>

webApplication 要素の下に追加する

DB アクセスの設定に合わせる

Postgres の JDBC ドライバの置き場所を指定

contextRoot を "/" に変更

Page 59: BluemixでGWTアプリケーションを動かす(2)

Liberty へのデータソース設定• server.xml は開発の際に多くのメンバと共有する必要があ

り、 password は多くの開発者の間で共有されます。 server.xml をうっかり平文でネットワークを通してやりとりしてしまうケースもあるでしょう。このため password が漏れるリスクがあります。

• DB の password が漏れにくくするために、 password のエンコード機能が用意されています。詳細は以下を参考にしてください。http://www-01.ibm.com/support/knowledgecenter/#!/SS7K4U_8.5.5/com.ibm.websphere.wlp.zseries.doc/ae/rwlp_command_securityutil.html

• ただ、このようにしたところで、少々漏れにくくなるだけです。なぜなら Liberty にはデコードのための全情報を与える必要があるからです。本番用とテスト用の DB は分けて、このように PC 上に設定するものはテスト用の DB に限定することをお勧めします。またテスト用 DB には機密情報を入れないように注意してください。

Page 60: BluemixでGWTアプリケーションを動かす(2)

EJB の追加• ステートレス・セッション・ビーンを追加します。

サーブレットブラウザ EJB JPA

エンティティ

クラス

テーブル

ここでトランザクションの管理を行う

Page 61: BluemixでGWTアプリケーションを動かす(2)

EJB の追加• Eclipse で File => New => Other を選び、 EJB => Session Bean を

選びます。

Page 62: BluemixでGWTアプリケーションを動かす(2)

EJB の追加

パッケージ名とクラス名を入力

Finish をクリック

Page 63: BluemixでGWTアプリケーションを動かす(2)

EJB の実装• EJB の中を実装します。

@Stateless@LocalBeanpublic class GreetingLogic { @PersistenceContext EntityManager em; public GreetingLogic() { } public void perform(String message) { Message msg = new Message(); msg.setMessage(message); em.persist(msg); }}

JPA を使用するためにEntityManager をインジェク

トします

エンティティ・クラスのインスタンスを作成して入力メッセージを設定して、 persist() で保存します。これによってテーブルにレコードが挿入されます

Page 64: BluemixでGWTアプリケーションを動かす(2)

EJB の呼び出し• 元の dbaccess.server.GreetingService から EJB を呼び出します。

public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

@Inject GreetingLogic greetingLogic; public String greetServer(String input) throws IllegalArgumentException { greetingLogic.perform(input);

// Verify that the input is valid. if (!FieldVerifier.isValidName(input)) {

EJB をインジェクトします

EJB を呼び出します

Page 65: BluemixでGWTアプリケーションを動かす(2)

persistence.xml の設定• persistence.xml ファイルが既に自動的に追加されているはずですが、

そこにデータソース定義を追加します。

<jta-data-source>jdbc/mydb</jta-data-source>

Page 66: BluemixでGWTアプリケーションを動かす(2)

実行構成の変更• Run => Run Configurations... を選びます。

Server タブを選び、 Run built-in server のチェックを外して、 applyボ

タンを押します

Page 67: BluemixでGWTアプリケーションを動かす(2)

実行してみる• これで準備ができたので実行します。まず Liberty を起動します。

Console にこのように表示されれば ok です。

• 次に dbaccess を起動します。これはこれまでと同じです。

Page 68: BluemixでGWTアプリケーションを動かす(2)

実行してみる• psql でデータベースを確認すれば、レコードが追加されるのが分かりま

す。

Page 69: BluemixでGWTアプリケーションを動かす(2)

Bluemix にデプロイ• それでは、 Bluemix にデプロイしてみましょう。

• Liberty と開発モード (Super dev mode) を停止し、 GWT Compile を実行しておいてください。

• 冒頭で述べた通り、今回は Java8 を使うことと、 Liberty の WebProfileを使用するので少々変わります。 cf login した後、 dbaccess/war ディレクトの下に行って以下の内容のファイルを、 manifest.yml というファイル名で作成します。---applications:- name: ruimodbenv: JBP_CONFIG_LIBERTY: 'app_archive: {features: [webProfile-7.0]}'

ここは自分のアプリケーション名に変更してください

yml ファイルはインデント ( 行頭のスペースの数 ) が重要なので注意してくだ

さい

Page 70: BluemixでGWTアプリケーションを動かす(2)

Bluemix にデプロイ• コマンドは以下のようになります。

$ cf push --no-start...$ cf set-env ruimodb JBP_CONFIG_IBMJDK 'version: 1.8.+'...$ cf services...name service plan bound apps last operationElephantSQL-3e elephantsql turtle ruimohello create succeeded...$ cf bs ruimodb ElephantSQL-3e...$ cf start ruimodb

manifest.yml を用意したのでアプリケーション名は不要です。 --no-start で、起動しないよう

にします

サービス名を確認して、バインドします

アプリケーションを起動します

アプリケーションが起動したら動作確認してください。データソースの定義は、Bluemix が自動的にやるため単にサービスをバインドするだけで済みます

Page 71: BluemixでGWTアプリケーションを動かす(2)

地図アプリケーションにデータアクセスを組込む

Page 72: BluemixでGWTアプリケーションを動かす(2)

前回アプリケーションの落穂拾い• 前回は、 Java 1.7 を使いましたが、今回は、 1.8 にしましょう。前回の

アプリケーションは以下から入手できます。http://www.ruimo.com/bluemix/samples/gwt/mymap04.zip

プロジェクトのファセットで、Java を 1.8 に変更します

Page 73: BluemixでGWTアプリケーションを動かす(2)

前回アプリケーショの落穂拾い• 現在地取得エラー

実際に動かしてみると、現在位置の取得は割と頻繁にエラーになるようです。いちいち alert() が表示されてわずらわしいので削除しておきます。

war/Mymap.jsp

function currentLoc(f) { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function(pos) { f(pos.coords.latitude, pos.coords.longitude); }, function(e) {// alert('現在地の取得が許可されていません。 '); } ); } else {// alert('現在地が取得できません。 '); }}

Page 74: BluemixでGWTアプリケーションを動かす(2)

Web プロジェクトに変換• ファセットを変更して Web プロジェクトに変換します。

Dynamic Web Module をチェックしてバージョンを 3.1

に、 JPA をチェックしてバージョンを 2.1 に

Runtime タブで Libertyを選択

Page 75: BluemixでGWTアプリケーションを動かす(2)

web ディレクトリを公開場所に

既存の WebContent を削除して、 war ディレクトリを

追加

Page 76: BluemixでGWTアプリケーションを動かす(2)

EJB を追加• プロジェクトを右クリックして、 New => Other... から EJB =>

Session Bean を選ぶ。

左の設定で Finish をクリックして作成

Page 77: BluemixでGWTアプリケーションを動かす(2)

テーブルの作成• 場所を格納するためのテーブルを作成します。 psql で接続してから以下

の SQL を実行します。

create table Places (id bigserial not null unique, name text not null, latitude double precision not null, longitude double precision);create index ix_place01 on places(latitude);create index ix_place02 on places(longitude);

今回はサロゲートキーを 64bit にしました(bigserial) 。緯度、経度にはインデックスを付けて

あります

Page 78: BluemixでGWTアプリケーションを動かす(2)

Place を JPA のエンティティに変換します

• まず、 Place にある parse() メソッドを外に抜き出します (JSONObjectは、クライアント側のクラスなので、サーバで使用するクラスに含まれているとエラーになります ) 。package mymap.client;

import com.google.gwt.json.client.JSONObject;

public class PlaceParser { static final PlaceParser THE_INSTANCE = new PlaceParser();

public static PlaceParser getInstance() { return THE_INSTANCE; }

public Place parse(JSONObject placeJson) { JSONObject geo = placeJson.get("geometry").isObject(); JSONObject loc = geo.get("location").isObject();

return new Place (placeJson.get("name").isString().stringValue(), loc.get("lat").isNumber().doubleValue(), loc.get("lng").isNumber().doubleValue()); }}

Page 79: BluemixでGWTアプリケーションを動かす(2)

Place から parse() を削除• すると MyMap.java がエラーになるので修正します (138 行目 ) 。

// places.add(Place.parse(results.get(i).isObject())); places.add(PlaceParser.getInstance().parse(results.get(i).isObject()));

Page 80: BluemixでGWTアプリケーションを動かす(2)

サロゲートキーを追加• id を保持できるようにします。

@Table(name = "places")public class Place implements Serializable { private static final long serialVersionUID = 286987229306285007L; private Long id; private String name; private double latitude; private double longitude;

Place() { name = ""; latitude = 0; longitude = 0; } public Place(String name, double latitude, double longitude) { this.name = requireNonNull(name); this.latitude = latitude; this.longitude = longitude; } public Long getId() {return id;} public String getName() {return name;}

Page 81: BluemixでGWTアプリケーションを動かす(2)

Place の JPA エンティティ化• Place を右クリックし、 JPA Tools => Make Persistent を選びます。

Annotate in Java を選ぶ

Finish

Page 82: BluemixでGWTアプリケーションを動かす(2)

Place の JPA エンティティ化

@Entity@Table(name = "places")public class Place implements Serializable { private static final long serialVersionUID = 286987229306285007L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private double latitude; private double longitude;

public Place() { name = "";

追加

public を追加

Page 83: BluemixでGWTアプリケーションを動かす(2)

persistence.xml の変更

<?xml version="1.0" encoding="UTF-8"?><persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="mymap"> <jta-data-source>jdbc/mydb</jta-data-source>

<class>mymap.shared.Place</class></persistence-unit>

</persistence>

追加

Page 84: BluemixでGWTアプリケーションを動かす(2)

EJB の実装• EJB を実装します。

@Stateless@LocalBeanpublic class MyPlaceLogic { @PersistenceContext EntityManager em;

public void addMyPlace(Place newPlace) { em.persist(newPlace); }

} persist() でinsert

Page 85: BluemixでGWTアプリケーションを動かす(2)

EJB の実装

public List<Place> myPlaces(double latitude0, double longitude0, double latitude1, double longitude1) {

double[] lat = {latitude0, latitude1}; double[] lng = {longitude0, longitude1}; Arrays.sort(lat); Arrays.sort(lng); List<Place> results = em.createQuery ("select p from Place p where " + "(p.latitude between :latitude0 and :latitude1) and " + "(p.longitude between :longitude0 and :longitude1)", Place.class) .setParameter("latitude0", lat[0]) .setParameter("latitude1", lat[1]) .setParameter("longitude0", lng[0]) .setParameter("longitude1", lng[1]) .getResultList(); results.forEach(p -> em.detach(p)); return results; }

指定された緯度、経度範囲のレコード抽出

between は昇順に指定する必要があるので sort(Google

API の戻りは昇順とは限らない )

クライントサイドに渡したいので、 JPA から detach() する

Page 86: BluemixでGWTアプリケーションを動かす(2)

EJB の呼び出しpublic class PlacesServiceImpl extends RemoteServiceServlet implements PlacesService { static final Settings settings = SettingsFactory.getInstance().getSettings(); @Inject MyPlaceLogic placeLogic;... @Override public void addMyPlace(Place newPlace) { placeLogic.addMyPlace(newPlace); }

@Override public List<Place> myPlaces(double latitude0, double longitude0, double latitude1, double longitude1) { return placeLogic.myPlaces(latitude0, longitude0, latitude1, longitude1); }}

EJB をインジェクトして

処理は EJB に移譲

Page 87: BluemixでGWTアプリケーションを動かす(2)

クライアント側の修正• 前回使用した、 bounds_changed イベントは実際に表示領域が変更さ

れた時にしか通知されないことが分かりました ( 起動直後は通知されない ) 。少し変更します。function refreshBounds(map) { currentMapBounds[0] = map.getBounds().getNorthEast().lat(); currentMapBounds[1] = map.getBounds().getNorthEast().lng(); currentMapBounds[2] = map.getBounds().getSouthWest().lat(); currentMapBounds[3] = map.getBounds().getSouthWest().lng();}

function showMap(latitude, longitude) { map = new google.maps.Map(document.getElementById('map-canvas'), { center: new google.maps.LatLng(latitude, longitude), zoom: 15 }); google.maps.event.addListener(map, 'click', function(e) { onMapClicked(e.latLng.lat(), e.latLng.lng()); });

pinCurrentLocAt(latitude, longitude); setInterval(pinCurrentLoc, 5000); setInterval(function() { refreshBounds(map); updateMyPlaces(); }, 5000);}

5秒に 1 回画面右の領域を再描画します

Page 88: BluemixでGWTアプリケーションを動かす(2)

クライアント側の修正• Mymap.java の initialize() も修正します。

native void initialize() /*-{ var that = this; $wnd.onMapClicked = function(latitude, longitude) { [email protected]::onMapClicked(DD)(latitude, longitude); }; $wnd.updateMyPlaces = function() { [email protected]::updateEastContent()(); }; $wnd.initialize(); }-*/;

src/mymap/client/Mymap.java

Page 89: BluemixでGWTアプリケーションを動かす(2)

環境変数• apiKey/serverApiKey を環境変数で指定していましたが、これは

Liberty の場合は、 server.env で指定します。

ダブルクリック

apiKey/serverApiKey を

指定

Page 90: BluemixでGWTアプリケーションを動かす(2)

Liberty の server.xml を変更• server.xml の webApplication 要素に contextRoot を指定します。

<webApplication id="mymap" location="mymap.war" name="mymap" contextRoot="/"/>

Page 91: BluemixでGWTアプリケーションを動かす(2)

PC 上で実行• 以上で完成です。まず Liberty にデプロイします。 Liberty を右クリック

して Add and Remove... を選び

Page 92: BluemixでGWTアプリケーションを動かす(2)

PC 上で実行

mymap を追加します

Page 93: BluemixでGWTアプリケーションを動かす(2)

PC 上で実行• Liberty を起動します。

プロジェクトを右クリックして、Run As => Web Application (GWT Super Dev Mode) を選

びます

Page 94: BluemixでGWTアプリケーションを動かす(2)

PC で実行• この状態だと Jetty も起動してポートがぶつかるので、一度停止し、

• Run => Run Configurations... を選びます。

チェックを外して、再度Runボタンで起動します

Page 95: BluemixでGWTアプリケーションを動かす(2)

PC で実行

現在表示地図領域内の登録施設が表示されます

今回のアプリケーションは、 mymap05.zip という名前で公開

されています

Page 96: BluemixでGWTアプリケーションを動かす(2)

Bluemix へのデプロイ• サーバ、 GWT 開発モード (Super dev mode) を停止します。

• GWT compile を実行しておきます。

• 残りの手順は既に解説した通りです。

• war/manifest.yml を作成します。

---applications:- name: ruimomapenv: JBP_CONFIG_LIBERTY: 'app_archive: {features: [webProfile-7.0]}'

ここは自分のアプリケーショ名にします

Page 97: BluemixでGWTアプリケーションを動かす(2)

Bluemix にデプロイ

$ cf push --no-start...$ cf set-env ruimomap JBP_CONFIG_IBMJDK 'version: 1.8.+'...$ cf services...name service plan bound apps last operationElephantSQL-3e elephantsql turtle ruimohello create succeeded...$ cf bs ruimomap ElephantSQL-3e...$ cf start ruimomap

manifest.yml を用意したのでアプリケーション名は不要です。 --no-start で、起動しないよう

にします

サービス名を確認して、バインドします

アプリケーションを起動します

アプリケーション名は、前ページのmanifest.yml で指定したものです

Page 98: BluemixでGWTアプリケーションを動かす(2)

付録

Page 99: BluemixでGWTアプリケーションを動かす(2)

サンプル• 前回同様、サンプルは以下の URL にあります。

http://www.ruimo.com/bluemix/samples/gwt

• myma05.zipデータベースアクセスが行えるようにしたもの。