はじめに
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を組み合わせた簡単なアプリケーション(認証、サービス呼び出し)などを説明していきたいと思います。


