Java EE 7 を 360 度探索する

JOSH JUNEAU
Josh Juneau:ア
プリケーション開
発者、システム・
アナリスト、DBA。
開発ではおもに
Java、PL/SQL、
Jython/Python
を利用。Jython
Monthly ニュース
レター、Jython
Podcast、Jython
Web サイトを管理
している。『Java
EE 7 Recipes: A
Problem-Solution
Approach』
(Apress、2013
年)、
『Introducing
Java EE 7: A Look
at What's New』
(Apress、2013
年)の著者。
Java API for Batch Processing や Java Message Service の利用方法と、WebSocket によ
るチャット・クライアントの作成方法を学習する
本最終回です。このシリーズ
記事は全 3 回シリーズの
では、Java EE 7 で拡張された
機能や、HTML5、WebSocket、
JavaScript Object Notation
(JSON)処理などの比較的新し
い Web 標準を使用して、最新
型のエンタープライズ・アプリ
ケーションを構築する方法につ
いて説明します。
このパート 3 では、パート 1
とパート 2 ですでに開発した
movieplex7 アプリケーションを
改良し、チケット売上の表示機
能、映画ポイントを貯める機能、
他のユーザーとのチャット機能
を追加します。
注:アプリケーションのすべ
てのソース・コードは、こちら
からダウンロードできます。
デモ・アプリケーションの概要
パート 1 とパート 2 では、
NetBeans および GlassFish 4 の
ダウンロード方法、インストー
ル方法、設定方法を学習しまし
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
た。本記事でもこの環境を利用
して、アプリケーションの構築と
デプロイを行います。これまで
に、JavaServer Faces(JSF)2.2
を使用し、さらにナビゲーショ
ン用の Faces Flow などの新し
いテクノロジーを活用してアプリ
ケーションを基礎から構築しま
した。Java Persistence API(JPA)
2.1、Java API for RESTful Web
Services(JAX-RS)、および
JSON Processing(JSON-P)1.0
を利用して、ビジネス・ロジッ
クやデータ操作を実装する方法
を確認しました。
これ以降は、このシリーズ
のパート 1 とパート 2 におい
て NetBeans IDE で作成した
Maven ベースのプロジェクトを
使用しながら手順を確認してく
ださい。
映画チケットの売上
本項では、Java API for Batch
Processing 1.0(JSR 352)を利
用して、各上映の映画チケット
の売上をインポートし、CSV ファ
イルから累積売上を読み取って
データベースに挿入します。
バッチ処理とは、一連のタス
クまたはジョブを実行する手法
です。ほとんどの場合、バッチ
処理のジョブは対話的な操作を
必要とせず、一括処理を目的と
して長時間実行されます。バッ
チ処理の用語に関する詳細は、
Java EE 7 Tutorial を参照してく
ださい。
クラスの生成:まず、映画の売
上を処理してデータベースに保
存するためのクラスを作成しま
す。
1.「Source Packages」を
右クリックし、「New」→
「Java Package」を選択
します。パッケージ名に
org.glassfish.movieplex7.
batch と入力し、「Finish」
をクリックします。
2. 新しく作成したパッケージ
を右クリックし、「New」
→「Java Class」を
選択します。名前に
SalesReader と入力します。
AbstractItemWriter を継
承するようにクラス定義を
変更し、インポート文を解
決します。
AbstractItemReader は
ItemReader インタフェー
スを実装しています。
ItemReader インタフェー
スには、項目のストリーム
を読み取るためのメソッド
が定義されています。
3. クラスレベルのアノテー
ションである @Named と
@Dependent を追加し、
インポート文を解決しま
す。
@Named アノテーショ
ンを追加することで、こ
の Bean をジョブ XML に
インジェクションできるよ
うになります。また、@
Dependent を追加するこ
とで、この Bean のインジェ
クションが可能になりま
JAVA TECH
Java EE 7 を 360 度探索する
ABOUT US
パート 3
JAVA IN ACTION
COMMUNITY
//new to java /
blog
31
リスト4
public void open(Serializable checkpoint) throws Exception {
reader = new BufferedReader(
new InputStreamReader(Thread.currentThread()
.getContextClassLoader().getResourceAsStream
("META-INF/sales.csv")));
}
図1
す。
4. このクラスに以下のフィールドを
追加し、reader を宣言します。
private BufferedReader
5. リスト 1 の open メソッドを追加
して、CSV ファイルを読み取る処
理を実装します。
この例では、CSV ファイルをア
プリケーションの META-INF ディ
レクトリ内に配置する必要があり
ます。META-INF ディレクトリは、
アプリケーション・ソース・パッ
ケージのルートに位置します。
6. readItem メソッドをオーバーラ
イドして、リスト 2 のコードに変
更します。インポート文を解決し
ます。
readItem メソッドは、ストリー
ムから次の項目を読み取ります。
ストリームの終了時は null を返
します。
7. org.glassfish.movieplex7.
batch パッケージに新しい Java
クラスを追加して、名前に
SalesProcessor と入力します。ク
ラス定義に以下のコードを追加
して、ItemProcessor を実装しま
す。
implements ItemProcessor
ItemProcessor の実装クラスで
は、入力項目を操作し、出力項
目を生成することができます。
8. クラスレベルのアノテーションで
ある @Named と @Dependent
を追加し、インポート文を解決
します。黄色の電球アイコンを
クリックして、「Implement all
abstract methods」を選択しま
す(図 1)。
9. processItem の実装をリスト 3 の
ように変更し、インポート文を解
決します。
processItem メソッドは新しい
Sales オブジェクトを作成し、次
に StringTokenizer を作成します。
この StringTokenizer を使用して、
渡されたオブジェクト内の各項目
を解析します。最後に、解析後
の項目値を Sales オブジェクトに
設定して返します。
10. org.glassfish.movieplex7.
batch パッケージ内に新しい
Java クラスを作成して、名前に
SalesWriter と入力します。クラ
ス定義に以下のコードを追加し
て、AbstractItemWriter を継承
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
すべてのリストのテキストをダウンロード
します。
extends AbstractItemWriter
11. クラスレベルのアノテーションで
ある @Named と @Dependent
を追加し、インポート文を解決し
ます。
12. 黄色の電球アイコンをクリッ
クして javax.batch.api.chunk.
AbstractItemWriter のインポー
ト文を追加します。インポート文
が追加された後、電球アイコン
をクリックして「Implement all
abstract methods」を選択し、
クラスに writeItems メソッドを
追加します。
13. データ・ストアにアクセスする
ために、以下の宣言を追加して
EntityManager インスタンスをク
ラスにインジェクションします。
@PersistenceContext
EntityManager em;
14. リスト 4 に示すように、
writeItems メソッド内のコードを
for ループに変更します。
このルー
プを使用して、バッチ実行時に
集約されたすべての Sales オブ
ジェクトを永続化します。
15. メソッドに @Transactional アノ
テーションを追加して、トランザ
クション制御を組み込みます。イ
ンポート文を解決します。
バッチ・ジョブの作成:次の作業
は、XML に手続き型のタスクを実装
することです。この例では、ジョブ
は 3 つの項目を含む 1 つのチャンク
(chunk)となります。3 つの項目と
は、<reader> 要素、<processor> 要
素、<writer> 要素であり、それぞれ
対応するクラス実装は SalesReader、
SalesProcessor、SalesWriter です。
XML 内にタスクを作成するためには、
以下の手順を実行します。
1. バッチ XML ファイルを格納す
る新しいフォルダを作成します。
「META-INF」を右クリックして、
「New」→「Folder」を選択し
COMMUNITY
リスト3
JAVA IN ACTION
リスト2
JAVA TECH
リスト1
ABOUT US
//new to java /
blog
32
@PersistenceContext
EntityManager em;
5. このクラスに getSalesData とい
うメソッドを追加します。このメ
ソッドは、@NamedQuery を使
用して表のすべての行を返します
(リスト 7)。インポート文を解決
します。
6. 売上を表示するビューを作成
します。「Web Pages」を右ク
リックし、「New」→「Folder」
を選択します。フォルダ名に
batch と入力し、「Finish」をク
リックします。新しく作成した
作成したフォルダを右クリック
し、「New」を選択して、「Faces
Template Client」を選択しま
す。ファイル名に sales と入力
し、WEB-INF/template.xhtml を
参照してテンプレートに指定し
て「Finish」をクリックします。
<ui:composition> タグ内のすべ
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
リスト8
リスト9
<?xml version="1.0"?>
<job id="endOfDaySales" xmlns=
"http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
<step id="populateSales" >
<chunk item-count="3" skip-limit="5">
<reader ref="salesReader"/>
<processor ref="salesProcessor"/>
<writer ref="salesWriter"/>
<skippable-exception-classes>
<include class="java.lang.NumberFormatException"/>
</skippable-exception-classes>
</chunk>
</step>
</job>
すべてのリストのテキストをダウンロード
ての内容を、リスト 8 のコードに
置き換えます。黄色の電球アイ
コンをクリックして、名前空間の
接頭辞と URI のマッピングを修
正します。
このページには dataTable が
含まれます。dataTable は、バッ
チ処理でデータベースにデータ
が挿入された後に、sales ファイ
ルの内容を表示するために使用
されます。また、
このページには、
ジョブを実行するボタンとページ
を更新するボタンを示す 2 つの
commandButton も含まれます。
7. template.xhtml ファイルを編集
し、リスト 9 のコードを追加して、
sales.xhtml ビューへのリンクを
埋め込みます。
8. 最後に、プロジェクトを実行し
て、左側のナビゲーション・メ
ニューの「Sales」リンクをクリッ
クし、Movie Sales ビューを開き
ます。「Run Job」ボタンをクリッ
クすると、バッチ・ジョブが開始
されます。このジョブにより CSV
ファイルが処理され、売上がデー
タベースの SALES 表に挿入され
ます。「Refresh」ボタンをクリッ
クすると、処理された売上のリス
トが表示されます(図 2)。
映画ポイント
movieplex7 アプリケーションに映画ポ
イント・システムを実装するために、
COMMUNITY
BatchRuntime を使用して新しい
JobOperator を取得しています。
次に、この新しい JobOperator
を使用して、eod-sales に記述さ
れたバッチ・プロセスを開始し
ます。この JobOperator は、ジョ
ブの停止や再開のために使用す
ることもできます。
3. クラスに @Named アノテーショ
ンを追加して、インジェクション
できるようにします。インポート
文を解決します。
4. 以下のように、このクラスに
EntityManager をインジェクショ
ンします。
リスト7
JAVA IN ACTION
ます。フォルダ名に batch-jobs
と入力し、「Finish」をクリックし
ます。
2. XML ファイルを作成します。
batch-jobs フォルダを右ク
リックし、「New」→「XML
Document」を選択します。ファ
イル名に eod-sales と入力しま
す。すべてデフォルト値のままに
して、「Next」をクリックし、
「Finish」をクリックします。
XML ファイルの内容は以下の
とおりです。
■■
<chunk> の item-count 属性:
ライターに渡される項目数(サ
ンプルでは 3 つ)
■■
<chunk> の skip-limit 属性:
スキップされる例外の数(サ
ンプルでは 5 つ)
■■
<skippable-exceptionclasses/>:チャンク処理でス
キップされる例外のセット
3. XML にジョブ定義を追加します。
新しく作成したファイルの内容
を、リスト 5 のコードに変更しま
す。
バッチ・ジョブの起動:バッチ・ジョ
ブの起動処理を実装します。
1. org.glassfish.movieplex7.
batch パッケージを右クリックし、
「New」→「Session Bean」を
選択します。名前に SalesBean
と入力し、「Finish」をクリックし
ます。
2. この新しいセッション Bean に、
リスト 6 の runJob メソッドを追
加します。
このコードでは、
リスト6
JAVA TECH
リスト5
ABOUT US
//new to java /
blog
33
2 digits, e.g. 12,12")
private String message;
すべてのリストのテキストをダウンロード
Class」を選択します。名前に
SendPointsBean と入力します。
Serializable を実装します。以下
のクラスレベルのアノテーショ
ンを追加して、ここで作成した
Bean を EL 式からインジェクトで
きるようにし、また、session ス
コープとして設定します。イン
ポート文を解決します。
図2
Java Message Service(JMS)2.0 とそ
の新規 API を使用します。JMS 2.0 で
は、以前のリリースと比較して、メッ
セージの送受信に必要なコード量が減
り、複雑性も低減されているため、開
発生産性が向上します。
注:JMS を操作するためには、アプ
リケーション・サーバー・コンテナ内
にトピックまたはキューを作成する必
要があります。そのためには、コード
を記述するか、アプリケーション・サー
バーの管理ユーティリティを使用しま
す。この例では、コードの記述による
キューの作成方法を説明します。
JSF マネージド Bean の作成:まず、
映画ポイント・データを収集してキュー
に送信するために、JSF ビューにバイ
ンドされる JSF マネージド Bean を作
成します。
1. movieplex7 アプリケーション内
に新しいパッケージを作成しま
す。「Source Packages」を右
クリックし、「New」→「Java
Package」を選択します。名
前に org.glassfish.movieplex7.
points と入力して、「Finish」を
クリックします。
2. 新しいパッケージ内にクラスを
作成します。パッケージを右
クリックし、「New」→「Java
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
@Named
@SessionScoped
3. このクラスにリスト 10 の String
フィールドを追加します。この
フィールドは、ポイント・デー
タを取得するための JSF の
inputText フィールドにバイン
ドされます。このフィールドの
getter/setter を生成します。エ
ディタ・ペインを右クリックし
て「Insert Code」を選択し、
「Getter and Setter」を選択
します。フィールドを選択して、
「Generate」をクリックします。
注:このフィールドでは、入力
されたテキストが必要な書式に
従っているかを確認するために、
Bean 検証アノテーションが使用
されます。
4. 以下のコードを追加して、このク
ラスに JMSContext と Queue の
インスタンスをインジェクション
します。インポート文を解決しま
す。javax.jms.Queue をインポー
トすることに注意してください。
@Inject
JMSContext context;
@Resource(mappedName =
"java:global/jms/
pointsQueue")
JMSContext は JMS 2.0 の
新規インタフェースであり、
Connection オブジェクトと
Session オブジェクトを 1 つのオ
ブジェクト内にまとめています。
注:Java EE に準拠した
アプリケーション・サー
バーには、java:comp/
DefaultJMSConnectionFactory
という名前のデフォルトの JMS
コネクション・ファクトリが含ま
れています。コネクション・ファ
COMMUNITY
JAVA IN ACTION
@NotNull
@Pattern(regexp = "^\\d{2},\\d{2}",
message = "Message format must be 2 digits, comma,
JAVA TECH
リスト10
ABOUT US
//new to java /
blog
34
@Inject
JMSContext context;
@Resource(mappedName=
"java:global/jms/
pointsQueue")
注:この例では @
JMSDestinationDefinition ア
ノテーションによってキューを
作成していますが、このキュー
を使用するためには、さらに
pointsQueue でクラスにキュー
をインジェクションする必要もあ
ります。
8. リスト 13 の receiveMessage() メ
ソッドを追加します。
このメソッドは、JMSContext
を使用して pointsQueue のコン
シューマを作成し、キューから同
期的に String メッセージを受信
します。
9. リスト 14 の getQueueSize とい
うメソッドを追加します。このメ
ソッドは現在キューにあるメッ
セージ数を返します。インポート
文を解決します。
このメソッドは、
QueueBrowser を作成し、これ
リスト14
リスト15
public void sendMessage() {
System.out.println("Sending message: " + message);
context.createProducer().send(pointsQueue, message);
}
JAVA TECH
作成します。
7. 以下のコードを追加して、
JMSContext と Queue のリソー
スをインジェクションします。こ
れらのリソースは、このクラス内
で使用します。インポート文を解
決します。javax.jms.Queue など
の正しいクラスをインポートする
ようにしてください。
リスト13
すべてのリストのテキストをダウンロード
を使用してキューの各メッセージ
をトラバースして合計に追加しま
す。
Facelet の作成:次に、映画ポイント
を入力し、メッセージ送受信機能の
シミュレーションを行うための Facelet
ビューを作成する必要があります。
1.「Web Pages」を右クリックし、
「New」→「Folder」を選択し
て、新しいフォルダを追加します。
フォルダ名に points と入力して、
「Finish」をクリックします。
2. このフォルダ内に、points.xhtml
という新しい XHTML ファイル
を作成します。このビューの
<ui:composition> 要素内のコー
ドをリスト 15 のコードに置き換
えます。必要に応じて黄色の電
球アイコンをクリックして、名前
空間の接頭辞と URI のマッピン
グを解決します。
このビューには、メッセー
ジ入力用のフィールドと、
sendMessage メソッドを呼び出
す commandButton があります。
このメソッドが呼び出された場
合、inputText 内のメッセージが
キューに追加され、queueSize
に 1 が加算されます。このビュー
のもう 1 つの commandButton
は、receiveMessage メソッド
を呼び出します。このメソッド
が呼び出された場合は、キュー
からメッセージが読み取られ、
queueSize から 1 が減算されま
す。
ABOUT US
クトリが明示的に指定されてい
ない場合に、このデフォルトの
ファクトリが使用されます。
5. JMS キューにメッセージを送信
するために、このクラスにリスト
11 のメソッドを追加します。
JMSContext の
createProducerメソッドを使用し
て JMSProducer を作成できます。
JMSProducer には、メッセージ
を構成して同期的または非同期
的に送信するための各種メソッ
ドがあります。JMSProducer の
sendメソッドを使用して、キュー・
インスタンスにメッセージを送信
します。キュー・インスタンスに
ついては、次の手順で作成しま
す。
6. org.glassfish.movieplex7.
points パッケージを右ク
リックし、「New」→「Java
Class」を選択します。名前に
ReceivePointsBean と入力しま
す。Serializable を実装し、リス
ト 12 に示すクラスレベルのアノ
テーションを追加します。
JMS 2.0 で導入された @
JMSDestinationDefinition アノ
テーションを使用することで、必
要なリソースのプロビジョニン
グをプログラムで行うことがで
き、アプリケーションの構成に
かかる管理上のオーバーヘッド
が削減されます。この例では、
このアノテーションを使用して
java:global/jms/pointsQueue と
いう名前の javax.jms.Queue を
リスト12
COMMUNITY
リスト11
JAVA IN ACTION
//new to java /
blog
35
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
<p/>
<h:outputLink value=
"${facesContext.externalContext.requestContextPath}
/faces/points/points.xhtml">
Points</h:outputLink>
すべてのリストのテキストをダウンロード
セージが受信されるたびに 1 減少しま
す。
映画チャット
本項では、WebSocket 1.0 API を使用
して movieplex7 の来場者用チャット・
ルームを構築します。WebSocket 1.0
API には、接続開始のためのハンドシェ
イクとデータ転送の方法を定義した、
単一 TCP 接続上での全二重 / 双方向
通信のプロトコルが備わっています。
Java EE 7 には、JSR 356 で定義され
COMMUNITY
SendPointsBean に追加された
Bean 検証によって生成されたも
のです。
3. フィールドのテキストにカンマ
を挿入して 12,12 とし、「Send
Message」をクリックします。
今度はエラー・メッセージが
表示されず、Queue Size が 1 増
加します(図 5)。
4.「Receive Message」ボタンをク
リックします。メッセージがキュー
から読み出されるため、Queue
Size が 1 減少します(図 6)。
任意の順序でメッセージの送受信を
繰り返します。Queue Size は、
メッセー
ジが送信されるたびに 1 増加し、メッ
ABOUT US
3. template.xhtml にリスト 16 の
コードを追加し、さらにアプリ
ケーションから points.xhtml
ビューにアクセスするための他
の outputLink コンポーネントも
追加します。
movieplex7 アプリケーションの実行:
1.「Points」リンクをクリックします
(図 3)。
現時点で、キューにメッセー
ジは 1 つも含まれていません。
2. フィールドに 1212 というテキス
トを入力し、「Send Message」
をクリックします。
図 4 のようなエラーが表示
されます。このメッセージは、
JAVA IN ACTION
リスト16
JAVA TECH
//new to java /
図3
図5
blog
図4
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
図6
36
public class ChatServer {
private static final Set<Session> peers =
Collections.synchronizedSet(new HashSet<Session>());
@OnOpen
public void onOpen(Session peer) {
peers.add(peer);
}
@OnClose
public void onClose(Session peer) {
peers.remove(peer);
}
@OnMessage
public void message(String message, Session client)
throws IOException, EncodeException {
for (Session peer : peers) {
if (!peers.equals(client)) {
peer.getBasicRemote().sendObject(message);
}
}
}
JAVA IN ACTION
終了時に呼び出されます。各メソッ
ドの Session パラメータには、接続
の開始または終了を要求するクライ
アントを定義します。
■■
@OnMessage アノテーションの付い
たメソッドは、メッセージの受信時
に呼び出されます。メソッドの第 1
パラメータはメッセージのペイロー
ド、第 2 パラメータは接続の相手を
定義したクライアント・セッションで
す。
このメソッドは、接続中のすべての
クライアントに、受信したメッセー
ジをブロードキャストします。
Web ビューの生成:次に、チャット・
クライアントの Web ビューを生成しま
す。
1.「Web Pages」を右クリックし、
「New」→「Folder」を選択
します。名前に chat と入力し、
「Finish」をクリックします。
2. 新しい XHTML ファイルを作成
します。ファイル名に chatroom
と入力し、WEB-INF/template.
xhtml を参照してテンプレートに
指定します。他の値はデフォルト
値のままにして、
「Finish」
をクリッ
クします。
3. <ui:composition> タグ内のすべ
ての内容を、リスト 18 のコード
に置き換えます。
このコードにより、チャット・
クライアントとして使用する
HTML フォームを構成します。こ
のフォームでは、チャット・ロ
グと現在のユーザー・リストを
表示するための 2 つの textarea
JAVA TECH
た WebSocket 用の標準 API が追加さ
れています。そのため、開発者は、カ
スタマイズされたフレームワークでは
なく共通 API を利用して、WebSocket
ソリューションを作成できるようになり
ました。
WebSocket 通信を実装するクラスの
作成:まず、WebSocket 通信を実装
するための Java クラスを作成します。
1. 新しいパッケージを作成しま
す。「Source Packages」を右
クリックし、「New」→「Java
Package」を選択します。パッ
ケージ名に org.glassfish.
movieplex7.chat と入力します。
2.「Source Packages」を右クリック
し、「New」→「Java Package」
を選択して、クラスを作成します。
クラス名に ChatServer と入力し
ます。
3. この新しいクラス内のコードをリ
スト 17 のコードに置き換えます。
インポート文を解決します。特
に、javax.websocket.Session を
インポートすることに注意してく
ださい。
ChatServer クラスのコードの実行内
容は以下のとおりです。
■■
@ServerEndpoint によって、このク
ラスが WebSocket エンドポイント
であることが示されます。value 属
性は、エンドポイントにアクセスす
るための URI を定義します。
■■
@OnOpen アノテーションの付いた
メソッドはセッションの開始時に呼
び出され、@OnClose アノテーショ
ンの付いたメソッドはセッションの
リスト18
ABOUT US
リスト17
COMMUNITY
//new to java /
}
すべてのリストのテキストをダウンロード
と、ユーザー名およびメッ
セージを入力するための入力
textField が使用されます。さら
に、WebSocket セッションを開
くボタン、メッセージを送信する
ボタン、セッションを切断するボ
タンの 3 つのボタンがあります。
この 3 つのボタンのすべてが
onclick 属性によって JavaScript
関数にバインドされます。この
JavaScript 関数で WebSocket 通
信を実装します。この HTML の
末尾付近にある <script> 要素
には、JavaScript ファイルである
blog
37
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
図7
websocket.js が示されています。
4. WebSocket 通信の実装を含
む JavaScript ファイルを作成
します。Web Pages に含ま
れる「chat」を右クリックし、
「New」→「Web」を選択して、
「JavaScript File」を選択します。
ファイル名に websocket と入力
して、「Finish」をクリックしま
す。websocket.js を編集し、リス
ト 19a と 19b のコードを追加し
ます。
この websocket.js 実装は、
ChatServer クラスに指定された
URI を付加することで、エンドポ
イントURI を作成します。その後、
新しい WebSocket オブジェクト
を作成し、このファイル内に実装
される JavaScript 関数に対して、
WebSocket イベント関数を割り
当てます。ユーザーがページ上の
「Join」ボタンをクリックすると、
ユーザー名が取得され、最初の
WebSocket オブジェクトの send
メソッドが呼び出されて、その
ユーザー名が渡されます。
メッセージの送信時に、関連
するデータが send_message 関
数にパラメータとして渡されま
す。この関数は、メッセージに
username を付加してすべてのク
ライアントにブロードキャストし
ます。メッセージを受信するた
びに onMessage メソッドが呼び
出され、ログイン・ユーザーの
リストが更新されます。ページ
上の「Disconnect」ボタンは、
WebSocket 接続を閉じる処理を
開始します。
5. WEB-INF/template.xhtml を編集
し、Item 2 の outputLink 要素
をリスト 20 のコードで上書きし
ます。
6. プロジェクトを実行し、画面左側
のメニューの「Chat Room」リ
ンク(図 7)をクリックしてチャッ
ト・ルームに移動します。
チャット・ルームの下部に
CONNECTED というメッセージが
表示されます(図 8)。
7. 別のブラウザを開き、URI
localhost:8080/movieplex7 を入
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
var wsUri = 'ws://'+ document.location.host
+ document.location.pathname.substr(0,
document.location.pathname.indexOf
("/faces")) + '/websocket';
console.log(wsUri);
var websocket = new WebSocket(wsUri);
var username;
websocket.onopen = function(evt) {
onOpen(evt);
};
websocket.onmessage = function(evt) {
onMessage(evt);
};
websocket.onerror = function(evt) {
onError(evt);
};
websocket.onclose = function(evt) {
onClose(evt);
};
var output = document.getElementById("output");
function join() {
username = textField.value;
websocket.send(username + " joined");
}
function send_message() {
}
COMMUNITY
リスト20
JAVA IN ACTION
リスト19b
JAVA TECH
リスト19a
ABOUT US
//new to java /
websocket.send(username + ": " + textField.value);
blog
すべてのリストのテキストをダウンロード
38
図8
(図 9)。
注:Chrome Developer Tools
を使用して、WebSocket のトラ
フィックを監視できます。
まとめ
本記事では、パート 1 とパート 2 で
開発した movieplex7 アプリケーショ
ンを改良し、映画の売上の計算機能、
映画ポイントの付与機能、他のユー
ザーとのチャット機能を追加しました。
本記事では以下のテクノロジーを使用
しました。
■■
Batch Processing for Java EE
■■
JMS 2.0
■■
WebSocket 1.0
この全 3 回のシリーズでは、Java EE
7 で利用できる新機能を駆け足で紹介
しました。Java EE 7 の詳細は、オン
ライン・チュートリアルをご覧ください。
</article>
COMMUNITY
されます。ブラウザ 2 で別の名前
(例:Duke2)を使用してセッショ
ンに参加すると、各ウィンドウの
ユーザー・リストが更新されます
JAVA IN ACTION
ます)、Duke としてチャット・ルー
ムに参加します。もう一方のブラ
ウザ・ウィンドウ(「ブラウザ 2」)
でも、ユーザー・リストが更新
JAVA TECH
力してチャット・ルームを開きま
す。いずれかのブラウザ・ウィン
ドウで「Join」をクリックし(こ
のブラウザを「ブラウザ 1」とし
ABOUT US
//new to java /
LEARN MORE
• このシリーズのパート1
• このシリーズのパート2
図9
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// MARCH/APRIL 2014
blog
39