第4回 Webサービス・プロバイダを作ろう(前編)

中林 紀彦
日本アイ・ビー・エム株式会社
2003/3/5

お天気情報提供Webサービスの作成

 データベースの準備が整ったら、Webサービス・プロバイダを作りましょう。

プロジェクトの準備

 Kylixを起動して、[ファイル]−[新規作成]−[その他]の[WebServices]タブで「SOAPサーバーアプリケーション」を選択します。

画面1 [新規作成]ダイアログボックス

 「WWWサーバーアプリケーション」の形式は「Apache DSOモジュール」を選びます。「SOAPモジュールのためのインターフェイスを作成しますか?」と聞かれるので、[はい]ボタンでSOAPモジュールのためのインターフェイスを作成します。

 [Webサービスの新規追加]ダイアログボックスでは、サービス名を[Weather]とします。

画面2 [Webサービスの新規追加]ダイアログボックス

 SOAPサーバを作成すると、4つのファイルがプロジェクトに追加されるので1度保存します。WeatherImpl.pas、eatherIntf.pasはデフォルトのまま、Unit1はWebModU.pas、Project1はWeatherSoapServer.dprというファイル名に変更しました。

データベース関連処理の追加

 ここまでできれば、メソッドを記述するだけで一応SOAPアプリケーションとして動作しますが、データベースを扱うためにSOAPデータモジュールをプロジェクトに追加します。[ファイル]−[新規作成]−[その他]の[WebServices]タブで「SOAPサーバーデータモジュール」を選択します。モジュール名は「DataMod」とします。空のデータモジュールが作成されるので、DataModU.pasとして保存します。

 プロジェクトに必要なファイルの準備ができたので、コーディングに入っていきましょう。まず、プロジェクトファイル(WeatherSoapServer.dpr)で、Apacheから呼び出すときのDSOモジュール名を「WeatherSoapServer_module」とします。

exports
  apache_module name 'WeatherSoapServer_module';

 次に、データモジュールにデータベース関連のコンポーネント、

  • SQLConnection×1(SQLConnection1)
  • SQLDataSet×2(SQLDataSet1、SQLDataSet2)
  • DataSetProvider×1(DataSetProvider2)

をDataModにドロップします。なお、データベース関連のコンポーネントについては第2回を参考にしてください。

画面3 必要なコンポーネント

 配置したコンポーネントの設定を行います。まずSQLConnection1をダブルクリックし、DB2Weatherという接続を作成して画面4のようにプロパティを設定します。また、LoginPromptを「False」にします。

画面4 SQLConnection1の設定

 SQLDataSet1は、

  SQLConnection SQLConnection1
  NoMetaData True

とします。CommandTextには、

'SELECT wtext from weather
        WHERE wpref = '東京都'
        AND wdate = date(days(CURRENT DATE) + 1)
        ORDER BY wdate'

というSQLを入力します。このSQLで、weatherテーブルから東京都の明日の天候をStringで取り出せます。

 SQLDataSet2は、

  SQLConnection SQLConnection1
  NoMetaData True

とし、CommandTextに、

'SELECT wdate, wpref, weather.wtext, wimage from weather, weather_img
        WHERE weather.wtext = weather_img.wtext AND wpref = :wpref
        AND (wdate = CURRENT DATE OR wdate = date(days(CURRENT DATE) + 1))

        ORDER BY wdate'

と入力します。Kylixでこのくらい長いSQL文を作成するのは少々厄介ですが、エディタ(XEmacs)を使ってSQL文を作成することもできます()。

注:EmacsをDB2と併用する際のヒント
http://www.ibm.com/jp/software/data/developer/library/techdoc/emacs.html

 パラメータwprefは、

  DataType ftString
  Size 10
  Value 東京都

としておきます(日本語の入力は[Ctrl]+[Space]キーです)。

画面5 オブジェクトインスペクタで設定した状態

 このSQL文で都道府県を引数に与えると、今日と明日の天候をStringと画像で取り出すことができます。

 最後のDataSetProvider2は、DataSetを「SQLDataSet2」に設定します。

インターフェイスの実装

 それではWebサービスを実装していきましょう。実は、「SOAPサーバーデータモジュール」を作成しているので、このままでもDataSetProvider2でWebサービスを提供することができます。ただし、ボーランド製品(DelphiやKylixなど)以外ではWebサービス・クライアントの実装が難しいので、一般的なインターフェイスも用意しておきます。

 WeatherImpl.pasに[ファイル]−[ユニットを使う]でDataModを追加し、WeatherIntf.pasとWeatherImpl.pasにオレンジの部分を追加します。

{ Invokable interface IWeather }

unit WeatherIntf;

interface

uses InvokeRegistry, Types, XSBuiltIns;

type
(*
  TEnumTest = (etNone, etAFew, etSome, etAlot);

  TDoubleArray = array of Double;

  TMyEmployee = class(TRemotable)
  private
    FLastName: AnsiString;
    FFirstName: AnsiString;
    FSalary: Double;
  published
    property LastName: AnsiString read FLastName write FLastName;
    property FirstName: AnsiString read FFirstName write FFirstName;
    property Salary: Double read FSalary write FSalary;
  end;
*)

  { Invokable interfaces must derive from IInvokable }
  IWeather = interface(IInvokable)
  ['{FEB5DC2D-B648-D711-9F6F-0002557BBD46}']

    { Methods of Invokable interface must not use the default }
    { calling convention; stdcall is recommended }
(*
    function echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
    function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall;
    function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall;
    function echoDouble(const Value: Double): Double; stdcall;
*)
    function getWeather: String; stdcall;
  end;

implementation

initialization
  { Invokable interfaces must be registered }
  InvRegistry.RegisterInterface(TypeInfo(IWeather));

end.
WeatherIntf.pas

{ Invokable implementation File for TWeather which implements IWeather }

unit WeatherImpl;

interface

uses InvokeRegistry, Types, XSBuiltIns, WeatherIntf;

type

  { TWeather }
  TWeather = class(TInvokableClass, IWeather)
  public
(*
    function echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
    function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall;
    function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall;
    function echoDouble(const Value: Double): Double; stdcall;
*)
    function getWeather: String; stdcall;
  end;

implementation

uses DataModU;
(*
function TWeather.echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
begin
  { TODO : Implement method echoEnum }
  Result := Value;
end;

function TWeather.echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdc
all;
begin
  { TODO : Implement method echoDoubleArray }
  Result := Value;
end;

function TWeather.echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall
;
begin
  { TODO : Implement method echoMyEmployee }
  Result := TMyEmployee.Create;
end;

function TWeather.echoDouble(const Value: Double): Double; stdcall;
begin
  { TODO : Implement method echoDouble }
  Result := Value;
end;
*)

function TWeather.getWeather: String; stdcall;
var
  dm: TDataMod;
begin
  dm := TDataMod.Create(nil);
                       
  dm.SQLDataSet1.Open;                              
  while not dm.SQLDataSet1.Eof do                   
  begin 
                                            
    Result := dm.SQLDataSet1.FieldValues['wtext'];
  
    dm.SQLDataSet1.Next;                            
  end; 
                                             
  dm.Free;
                                          
end;

initialization
  { Invokable classes must be registered }
  InvRegistry.RegisterInvokableClass(TWeather);

end.
WeatherImpl.pas

 WeatherImpl.pasでは、getWeatherというメソッドを定義しています。このメソッドでは、

データモジュールをCreate
DataSetをOpen
結果の取り出し
データモジュールを解放

といった処理を行っています。

 インターフェイスを作成する際に、サンプルメソッドの生成にチェックを付けていたので、「(* *)」でコメントアウトされた部分にサンプルが記述されています。これを参考にすればデータ型やメソッドを追加できるので、メソッドを追加してみてください。例えばSQLDataSetコンポーネントを追加して、「values CURRENT DATE」というSQLで今日の日付を取り出すといったメソッドを追加するのも良いかもしれませんね。

 以上で、Webサービス・プロバイダアプリケーションができあがりました。Kylixのコンポーネントと一般的な方法の2通りのインターフェイスでサービスを提供できるプロバイダです。特に、前者はコンポーネントをドロップし、プロパティを設定して取り出すデータを指定するという開発工程であり、ほんの数分でWebサービス・プロバイダができてしまいます。これぞビジュアル開発といったところです。

 コンパイルしてエラーがなければ、libWeatherSoapServer.soを/usr/local/apache/libexec/以下へコピーします。

 次回はいよいよ最終回です。今回作成したWebサービス・プロバイダを公開する方法、そしてこのプロバイダを利用するサンプルWebサービス・クライアントを紹介します。

2/2

Index
Kylix 3とDB2で作るWebサービス・アプリケーション
 第4回 Webサービス・プロバイダを作ろう(前編)
  Page 1
データベースの準備
 データベース、テーブル、インデックスの作成
 データの挿入
  Page 2
お天気情報提供Webサービスの作成
 プロジェクトの準備
 データベース関連処理の追加
 インターフェイスの実装

連載 Kylix 3とDB2で作るWebサービス・アプリ


 Linux Squareフォーラム プログラミング関連記事
特集:オブジェクト指向に生まれ変わるPHP5[前編]
現在開発中のPHP5は、オブジェクト指向機能が大幅に強化される。次世代PHPはどのような言語になるのか?
特集:Windows開発者に贈る Kylixの全貌
注目の開発環境「Borland Kylix」がいよいよ見えてきた。ここに、英語版の発売を目前に控えたKylixの機能やアーキテクチャを紹介しよう
特集:Kylixプログラミング作法
GUIの構築やコンポーネントとコードの関係、 Object Pascalの仕様など。 これらの点を、実際に日本語ベータ版でプログラミングしながら分かりやすく解説
連載:PHP4で作るWeb-DBシステム(全5回)
PHPはWebサーバとデータベースを結びつけるものだ。そのためPHPでの開発を開始するには、OS、データベース、Webサーバ、そしてPHPと、多くのソフトウェアのインストールを行う必要がある
連載:ステップ・バイ・ステップ・シェルスクリプト(全7回)
Linuxの中でシェルスクリプトはネットワークの設定、デーモンの起動など重要な役割を果たしている。この連載では、シェルスクリプトで実用的なプログラムを組むことを目標にして、シェルの基本的な知識を説明する
連載:Kylix 3とDB2で作るWebサービス・アプリ(全5回)
Kylix 3とDB2 V8.1を使って、Webサービス・アプリを作ってみよう。トライアル版も用意されているので、実際に試しながら読んでほしい

MONOist組み込み開発フォーラムの中から、Linux関連記事を紹介します


Linux & OSS フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Linux & OSS 記事ランキング

本日 月間