はじめに
Curl ORBは、CurlからPOJO(Plain Old Java Object)で作成されたサービスをコールするツールで、データ通信にバイナリフォーマットを採用しているため、高速なデータ通信が可能となります。CurlとサーバサイドJavaとの連携が容易に実現できるため開発効率が大幅に向上します。このCurl ORBを利用して、Spring Frameworkと連携したアプリケーション開発方法を説明していきます。
ダウンロード
まずは、サンプルコードを用いて、Curl ORBの動作を見ていただき、そのコードの説明をしたいと思います。
開発ツールのダウンロードおよびセットアップ
以下のツールをダウンロードし、インストールします。
- Curl IDE 6.0
- Eclipse 3.4(Eclipse IDE for Java EE Developersをダウンロード)
- Apache Tomcat6.0
Curl ORBとサンプルコードのダウンロード
以下のモジュールをダウンロードします。
- Curl ORB 0.6(curl-orb_0.6_stable_bin.zipをダウンロード)
- サンプルコード
開発環境セットアップ
1)Eclipseで新規プロジェクト作成
Eclipseを開き、新規プロジェクトを作成します。メニューからFile -> New -> Otherを選択します。
上記画面からWeb/Dynamic Web Projectを選択し、Nextボタンを押下します。
上記画面にてProject nameにcurl-orb-serverを入力し、Finishボタンを押下します。
2)Curl ORBモジュールのセットアップ
ダウンロードしたCurl ORBのzipファイルを解凍し、java/webディレクトリ配下にあるWEB-INFとindex.htmlをEclipseのProject Explorer上のcurl-orb-server/WebContent配下に上書きコピーします。
3)サンプルのセットアップ
ダウンロードしたサンプルのzipファイルを解凍し、java/webディレクトリ配下にあるWEB-INFを上記同様WebContent配下に上書きコピーします。この中には、既にSpring Framework 2.5が梱包されています。
4)Tomcat起動
Eclipse上のcurl-orb-serverプロジェクトを選択し、右クリック -> Run As -> Run on Serverを選択します。
上記画面でTomcatのホームディレクトリを選択し、Nextを押下します。
上記画面でFinishを押下しますと、Tomcatが起動され、配備されたCurl ORBも立ち上がります。
5)Curlセットアップ
ダウンロードしたCurl ORBモジュール配下に、curlディレクトリがあります。この上にサンプル配下のcurlディレクトリを上書きします。
6)稼動確認
上記curlディレクトリのsample1.curlをダブルクリックしますと以下の画面が立ち上がります。
上記、add using sessionもしくはadd using springボタンを押下しますと、Curl ORB経由でサーバサイドのJavaのメソッドを実行し、画面上に足し算の結果が表示されます。
サンプルコードのインポート
EclipseのメニューからFile -> Importを選択します。
上記画面で、From directoryでサンプルのjava/srcディレクトリを選択し、表示されたsrcをチェックします。次にInto folder欄にcurl-orb-server/src/sampleを入力もしくは選択し、Finishボタンを押下します。
上記のようにsampleパッケージと、Foo.java、Hoge.java、Person.java、SampleException.javaのソースコードがインポートされます。
サンプルコード説明~CurlからJavaのメソッドを呼ぶ~(1)
sample/Hoge.javaを開きます。
package sample; import org.springframework.stereotype.Service; import com.curlap.orb.security.RemoteService; /** * spring framework sample */ @Service("hoge") @RemoteService public class Hoge { public String hello(String name) { return "Hello " + name + "!"; } public int add(int i1, int i2) { return i1 + i2; } public Person getPerson() { Person person = new Person(); person.setName("hoge"); person.setAge(20); person.setSex(true); return person; } public Object echo(Object v) { return v; } public void throwException() throws SampleException { throw new SampleException("happned sample exception!"); } }
このHogeクラスは単純なPOJOで作成されたサービスクラスです。このクラスをSpringにBeanとして登録するため、@Serviceアノテーションを利用しています。(idは"hoge")この@Serviceアノテーションを付与したサービスクラスをSpringに自動的に登録させるために、Springの設定ファイルであるapplicationContext.xmlファイルに、以下の一行を追加します。
<context:component-scan base-package="sample"/>
実際の中身については、WebContent/WEB-INF/applicationContext.xmlを参照ください。
また、@RemoteServiceアノテーションというものがありますが、これはCurl ORBのアノテーションで、クライアントからのアクセス制御のために使用します。Curl ORBでは、4つのパラメータ(none、development、test、production)を指定でき、web.xmlでこれを切り替えることができます。以下はweb.xmlの一部です。
<context-param> <param-name>com.curlap.orb.environment</param-name> <param-value>development</param-value> </context-param>
例えば、@RemoteService(Environment.DEVELOPMENT)と指定したサービスクラスは、web.xmlでdevelopmentと指定した場合のみアクセス可能で、test、productionでサーバが稼動している場合はアクセスできません。また、@RemoteService(Environment.PRODUCTION)と指定した場合は、すべてのパラメータでアクセス可能となります。サンプルコードのようにEnvironmentを省略した場合は、Environment.PRODUCTIONがセットされます。ちなみに、noneの場合は@RemoteServiceのアノテーションなしで、アクセス可能となります。詳細についてはこちら(セキュリティ設定)を参照ください。
また、サービスクラス内で利用するデータクラスPersonや例外クラスSampleExceptionを以下のように用意しています。データクラスは、CurlとJavaの通信用のデータとなります。データクラス内で利用できる型は、プリミティブ型、String、配列、リスト、連想配列、日付型、BigInteger、BigDecimal、Personのようなユーザ定義クラス、Curl特有のRecordSetなどがあります。詳しくはこちら(いろいろなデータ型のサポート)を参照ください。
package sample; /** * data class sample */ public class Person implements java.io.Serializable { private static final long serialVersionUID = -8122761322568223564L; private String name; private int age; private boolean sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } }
package sample; /** * sample exception */ public class SampleException extends Exception { private static final long serialVersionUID = -9029774938234791120L; public SampleException(String message) { super(message); } }
サンプルコード説明~CurlからJavaのメソッドを呼ぶ~(2)
次にCurl側のコードを見ていきたいと思います。
curl/SAMPLEディレクトリ配下にFoo.scurl、Hoge.scurl、Person.scurl、SampleException.scurl、load.scurlがありますが、これらはCurl ORBのコード生成ツールから自動的に生成されたコードです。
例えばサービスクラスHogeを一部見てみますと以下のようなコードが生成されています。
||| ||| Curl ORB for java (version 0.6) ||| This code was generated by the Curl code generator automatically. ||| package name : SAMPLE ||| generated date : 2009-04-01 14:03:48.499000 ||| {import * from COM.CURLAP.ORB} {define-class public Hoge {inherits ApplicationContextClient} {constructor public {default server-url:#Url = null} {construct-super.ApplicationContextClient "hoge", server-url = server-url} } {method public {async-hello v0:String, ...:EventHandler}:AsyncWorker {return {self.async-invoke "hello", arguments = {FastArray v0}, {splice ...}} asa AsyncWorker} } {method public {hello v0:String}:#String {return {self.invoke "hello", arguments = {FastArray v0}} asa #String} } {method public {async-get-person ...:EventHandler}:AsyncWorker {return {self.async-invoke "getPerson", {splice ...}} asa AsyncWorker} } {method public {get-person}:#Person {return {self.invoke "getPerson"} asa #Person} } ...
JavaのコードからCurlのコードを生成する場合、以下のルールに従い、生成されます。
- パッケージ名は大文字となります(Curlの一般的なネーミングルール)。
- メソッド名は、すべて小文字で単語の区切りはハイフンとなります(java:getPerson -> Curl:get-person)。
- クラス名は同様です。
- 同期通信用メソッドは、そのままで、非同期通信用メソッドは"async-"という名前が付与されます。
次にデータクラスであるPersonを見ます。
{define-class public serializable Person field private _name:#String field private _age:int field private _sex:bool {getter public {age}:int {return self._age asa int} } {getter public {sex}:bool {return self._sex asa bool} } {getter public {name}:#String {return self._name asa #String} } {setter public {age v:int}:void set self._age = v } {setter public {sex v:bool}:void set self._sex = v } {setter public {name v:String}:void set self._name = v } }
こちらは、以下のルールに従い、生成されます。
- パッケージ名は大文字となります(Curlの一般的なネーミングルール)。
- メソッド名は、すべて小文字で単語の区切りはハイフン(-)となります(java:getPerson -> Curl:get-person)。
- クラス名は同様です。
- ゲッター・セッターが存在する場合、フィールド名は、アンダーバー(_)付きになります。
- ゲッター・セッターはフィールド名となります。
では上記の生成されたクラスを利用する方法を説明していきます。
と言っても、Curlのメソッド・コールと同様ですので、Curl ORBやJavaを意識することなく、利用することが可能です。以下がサンプルに含まれるソースコード(sample1.curl)の一部です。
|| インスタンス生成 def foo = {Foo} || メソッド呼び出し def person = {foo.get-person} def hello = {foo.hello {non-null person.name}} def result = {foo.add {t1.value.to-int}, {t2.value.to-int}}
{hoge.get-person}で、Java側のSpringで管理されているHogeインスタンス(idが"hoge")のgetPersonメソッドを呼び出し、結果(Personオブジェクト)を取得し、personという変数にセットしています。また、{hoge.add 数字, 数字}を実行すると、Java側のaddメソッドが呼び出され、足し算の結果が戻り値として返ります。上記の例ですとresult変数に足し算の結果がセットされます。
ちなみに、Curl ORBが動いているサーバ(ここではApache Tomcatサーバ)がlocalhost:8080以外で動いている場合は、サーバURLを変更する必要があります。これにはset-default-server-urlプロシージャを利用し、変更します。この行は他の処理よりも前に一行のみ記述してください(例えば、アプレットが呼び出された直後に挿入)。
{set-default-server-url {url "http://hogehoge:8888/test-server"}}
詳細はこちら(サーバURLを指定)を参照ください。
サンプルコード説明(その他)
サンプルコードを元に、単純にCurlからJavaのメソッドを呼び出す以外の機能も見ていこうと思います。
1)非同期通信
非同期通信を行うためには、まず"async-"で始まるメソッドを実行します。例えば以下のサンプル(sample2.curl)ですとechoというJavaもメソッドを非同期で呼ぶため、async-echoというメソッドを呼び出しています。
{hoge.async-echo 100, || 引数にAsyncCallbackEventハンドラーを記述します。 {on e:AsyncCallbackEvent do {if-non-null ex = e.exception then || Exceptionが発生した際の処理を記述 {popup-message ex.message} else || 成功した際の処理を記述 || 結果はAsyncCallbackEventのobjプロパティで取得できます。 def result = e.obj asa int {disp.add result} } } }
非同期にメソッドを実行するためには、終了したときの処理を、AsyncCallbackEventハンドラー内に記述します。上記サンプルのように、例外が発生しているかチェックし、例外(AsyncCallbackEventのゲッターexceptionで取得)が発生していたら、メッセージ表示し、成功したら画面に結果(AsyncCallbackEventのゲッターobjで取得)を表示({disp.add result})しています。このハンドラーをasync-echoメソッドの最後の引数としてセットします。
2)例外ハンドリング
Curl ORBでは、Java側で例外が発生しますと、デフォルトではすべてORBServerExceptionとしてcatchします。ただし、Javaで発生したExceptionの種類によって、クライアント側で他のExceptionを発生させたい場合や、JavaのExceptionをそのままCurlでcatchしたい場合が出てくると思います。そこで、bind-exceptionプロシージャを利用しますとこれが実現できます。以下はサンプル(SampleException.scurl)です。
||| ||| Curl ORB for java (version 0.6) ||| This code was generated by the Curl code generator automatically. ||| package name : SAMPLE ||| generated date : 2009-04-01 14:03:20.489000 ||| {import * from COM.CURLAP.ORB} {define-class public SampleException {inherits Exception} {constructor public {default message:String} {construct-super message} } } || JavaとCurlのExceptionをバインドする。 || サーバサイドでsample.SampleExceptionが発生した場合、 || クライアント側でもSampleExceptionが発生するようになる。 {bind-exception "sample.SampleException", || java Exception SampleException || Curl Exception }
SampleExceptionはコード生成ツールで生成されたコードでbind-exceptionは手動で追加したコードです。このコードを追加することで、Java側でsample.SampleExceptionが発生した場合、Curl側ではORBServerExceptionではなく、SAMPLE.SampleExceptionが発生します。これを以下のようにtry - catchします。
{try || メソッド呼び出し {hoge.throw-exception} catch e:SampleException do {disp.add "[exception] " & e.message} }
Hogeクラスのthrow-exceptionメソッドは、Java側でSampleExceptionを発生されるサンプルです。
以上がサンプルコードの説明となり、Curl ORBの中心的な機能を説明しました。各機能詳細については、CurlORB6.0ページを参考にすることができます。次回以降は、コード生成方法、テストスタブ利用方法、Spring FrameworkとCurl ORBを組み合わせた簡単なアプリケーション(認証、サービス呼び出し)などを説明していきたいと思います。