はじめに
前回はサンプルコードを用いて、Curl ORBの動きを説明していきました。今回は、実際にコードを記述して、開発する手順を説明していきたいと思います。
Javaコードの作成(1)
前回説明したEclipseプロジェクトに新規サービスを追加していきます。まずはサービスクラスとデータクラスを作成します。サービスクラスは実際にCurlから呼び出すクラスとなり、データクラスはそのやりとりをするデータのクラスとなります。具体的には、メソッドの引数や戻り値となるクラスです。引数や戻り値にサポートしている型(プリミティブ、String、配列、List、Map、BigInteger、BigDecimal、Date、Timestamp、RecordSetなど)を定義する場合は、データクラスを作らなくてもよいです(Curl ORBでサポートされる方はこちらを参照ください)。
ここではまず、demoパッケージを作成し、その配下にデータクラスProductを作ります。EclipseのProject Explorerからcurl-orb-serverを選択し、New→Packageを選択し、demoパッケージを作成します。新しいパッケージをSpringで管理できるように、以下のように<context:component-scan base-package="demo"/>を1行追加します。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:component-scan base-package="sample"/> <context:component-scan base-package="demo"/> </beans>
次に、demoパッケージを右クリックし、New→Classを選択します。
上記画面で、NameにProductを入力し、Interfaceにjava.io.Serializableを選択すると空のProductクラスが作成されますので、以下のようにフィールドとgetter/setterを追加します。
package demo; import java.io.Serializable; public class Product implements Serializable { private static final long serialVersionUID = 7071029986547765264L; private String id; private String name; private int price; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
Javaコードの作成(2)
今回はデータベースの代わりにProductデータを保存するクラスを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Classを選択します。
New Java Class画面で、NameにProductStoreを入力し、Superclassにjava.util.ArrayList<Product>を入力して、Finishボタンを押下します。
作成されたファイルProductStoreを以下のように修正します。@Componentを付与し、Spring上でBean id:storeとして管理されるようにします。
package demo; import java.util.ArrayList; import org.springframework.stereotype.Component; @Component("store") public class ProductStore extends ArrayList<Product> { private static final long serialVersionUID = -2656699492233321360L; }
サービスクラスとして、インターフェースProductServiceと実装クラスProductServiceImplを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Interfaceを選択します。
nameをProductServiceにしてFinishを押下すると、ProductService.javaファイルが作成されますので、以下のように編集します。
package demo; public interface ProductService { /* Product登録メソッド */ public void regiseterProduct(Product product); /* Product取得メソッド */ public Product[] getProducts(); }
次に、ProductServiceの実装クラスであるProductServiceImplを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Classを選択します。
nameをProductServiceImplにしてFinishを押下すると、ProductServiceImpl.javaファイルが作成されますので、以下のように編集します(Springに自動的に登録させるため、@Serviceアノテーションを付与します。また、@RemoteServiceアノテーションはCurl ORBのセキュリティ制御のために付与します)。
package demo; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.curlap.orb.security.RemoteService; @RemoteService /* Curl ORBアクセス制御アノテーション */ @Service("productService") /* Springサービスアノテーション */ public class ProductServiceImpl implements ProductService { /* ProductStoreをインジェクト */ @Resource private ProductStore store; public void regiseterProduct(Product product) { store.add(product); } public Product[] getProducts() { return store.toArray(new Product[]{}); } }
これで、外部に公開するサービス:ProductService(実装クラス:ProductServiceImpl)とデータクラス:Product、仮データベース:ProdctStoreが作成されました。この時点でTomcatサーバを起動します。
上記画面で、Tomcatサーバを起動します。
ここまでの説明ではJavaが主体でしたので、まだCurlは関係ありません。次ページ以降でCurl部分について実装していきます。
Curlコードの生成(1)
Javaのサービスができたら、次にCurlのコードを生成します。ちなみに実際の開発では、コード生成時点でJavaのメソッドをすべて実装しておく必要はありません。クラスやメソッドの名称や引数・戻り値さえ変わらなければ、Curlコードを再度生成しなおさなくてかまいません。
まずは、curl/code-generator.dcurlをダブルクリックし、コード生成ツールを立ち上げます(コードを生成するには、サーバを起動しておく必要があります)。
Configurationを選択します。ここではBase save directoryに任意の保存先ディレクトリを選択し、saveボタンを押下します。
元の画面に戻り、Data Classを選択し、Nextボタンを押下します。
Browseボタンを押下しますと下記ポップアップ画面が表示されます。
ここで、データクラスであるProduct - demo -を選択します。
上記のようにdemo.ProductがClass nameにセットされます。これは、手動で入力してもよいです。Nextボタンを押下します。
データクラスのフィールド名やメソッド名などの詳細が表示されます。名称や、非同期メソッドの追加などが行えます。Generatorボタンを押下すると、Configuration画面のBase save directoryにセットしたディレクトリに以下のように出力されます(パッケージ名/クラス名.scurlとパッケージ名/load.scurl)。
||| ||| Curl ORB for java (version 0.6) ||| This code was generated by the Curl code generator automatically. ||| package name : DEMO ||| generated date : 2009-04-07 11:59:29.314000 ||| {define-class public serializable Product field private _id:#String field private _name:#String field private _price:int {getter public {price}:int {return self._price asa int} } {getter public {name}:#String {return self._name asa #String} } {getter public {id}:#String {return self._id asa #String} } {setter public {id v:String}:void set self._id = v } {setter public {price v:int}:void set self._price = v } {setter public {name v:String}:void set self._name = v } }
Curlコードの生成(2)
次にサービスクラスを生成します。curl/code-generator.dcurlをダブルクリックし、起動します。
Service Class(DI)を選択し、Nextボタンを押下します。
Browseボタンを押下します。
ProductServiceImplクラスに指定した@ServiceアノテーションのproductServiceを選択します。
productServiceがセットされますので、Nextボタンを押下します。
当画面でもNextを押下します。
クラスの詳細画面が表示されるので、Generatorボタンを押下します。これで、curl/ProductService.scurlも以下のように生成されました。
||| ||| Curl ORB for java (version 0.6) ||| This code was generated by the Curl code generator automatically. ||| package name : DEMO ||| generated date : 2009-04-07 12:05:34.835000 ||| {import * from COM.CURLAP.ORB} {define-class public ProductService {inherits ApplicationContextClient} {constructor public {default server-url:#Url = null} {construct-super.ApplicationContextClient "productService", server-url = server-url} } {method public {regiseter-product v0:Product}:void {self.invoke "regiseterProduct", arguments = {FastArray v0}} } {method public {get-products}:#{FastArray-of #Product} {return {self.invoke "getProducts"} asa #{FastArray-of #Product}} } }
コード生成ツールの詳細な説明は「コード生成ツール・マニュアル」を参照ください。
CurlからJavaのサービスを呼ぶ
curl/project.cprjをダブルクリックし、Curl IDEでプロジェクトを開きます。
メニューから、プロジェクト→プロジェクトの追加を選択し、curl/DEMO/load.scurlを選択すると、DEMOパッケージがロードされます。
テスト用のCurlファイルを作成するため、Curl IDEのメニューからファイル→新規を選択します。
ファイル名にtest.curlを選択し、OKボタンを押下します。そして、以下のようにサービス呼び出しのコードを追加します。
{curl 6.0 applet} {curl-file-attributes character-encoding = "shift-jis"} {applet manifest = "manifest.mcurl", {compiler-directives careful? = true} } {import * from DEMO} {do || データクラスProduct作成 def p1 = {Product} set p1.id = "0001" set p1.name = "abc" set p1.price = 5000 || データクラスProduct作成 def p2 = {Product} set p2.id = "0002" set p2.name = "xyz" set p2.price = 3000 || サービスクラスのインスタンス生成 def service = {ProductService} {service.regiseter-product p1} || registerProductメソッド呼び出し {service.regiseter-product p2} || registerProductメソッド呼び出し {if-non-null products = {service.get-products} then || getProductsメソッド呼び出し {for p in products do || コンソールにサーバから取得したProductを出力 {dump p.id, p.name, p.price} } } }
これで、test.curlをダブルクリックし実行すると、上記コードが実行され、Curlコンソールにサーバに保存されているProductがすべて出力されます。
このようにCurl ORBを使えば、CurlとJavaの通信を容易に実現することが可能です。後は、サーバから取得したデータを画面の各項目にセットしたり、画面の各項目の値をサーバに送信したりすることで、リッチクライアントな画面を開発することができます。