IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  SOA and Web services | Rational  >

連載「作る!SOAアプリケーション」:第6回 抽象インターフェースから作るサービス

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません


レベル: 中級

米持 幸寿, テクノロジー・エバンジェリスト, IBM

2006年 5月 10日

連載第5回の前回、書籍検索のインターフェースをデザインしてみる作業を紹介しました。
このようにして考え出されたインターフェースは、なんらかの方法で表現しなければなりません。

まずは表に

まずはとても古い方法からいきましょう。表にしてみる、という手です。日本人はとにかく表が好きです。たぶん、インターフェースの検討会議などを行うときも、プロジェクターに表を投影しながら議論することになります。ですから、表にすることはけっこう重要です。

表にするときも、インターフェースの作りをつねに意識します。それは、インターフェース型(portType)、操作(operation)メッセージ(message)という階層構造と、メッセージに使われるデータの型が必要である、ということです。

筆者は通常、次のような表でデータ構造とインターフェースを記述していきます。


表1.書籍情報
データ型名メンバー説明
BookInfotitle文字列書籍のタイトル
subtitle文字列サブタイトル
author文字列筆者名
publisher文字列出版業者
isbn文字列ISBN番号
picture文字列写真
price整数価格

表2.書籍検索結果データ
データ型名メンバー説明
SearchBooksResultItemlinenumber整数行番号
isbn文字列ISBN番号
title文字列タイトル
author文字列著者名

表3.書籍検索結果
データ型名メンバー説明
SearchBooksResultresulttotal整数検索した結果のヒット数
resultsSeachBooksResultItem[ ]書籍検索結果データの配列

表4.顧客情報
データ型名メンバー説明
Customercustomerid文字列顧客番号
name文字列顧客名
address文字列住所
age整数年齢
tel整数電話番号

表5.書籍注文明細行
データ型名メンバー説明
BookOrderItemisbn文字列ISBN番号
quantity整数冊数
subtotal整数明細合計

表6.書籍注文データ
データ型名メンバー説明
BookOrderitemsBookOrderItem[ ]注文明細行の配列
customerCustomer顧客情報
ordernumber文字列注文番号
primarytotal整数小計
tax整数消費税
total整数合計

表7.書籍注文インターフェース

ポート型名:「 BookSearcher

操作名   メッセージ名メッセージ内容説明
getCategories最初の一文字を指定して、カテゴリー一覧を取得する
GetCategoriesRequestinitial文字列カテゴリー名の最初の一文字
GetCateoriesResponsecategories文字列[ ]カテゴリー名一覧
searchBooksByCategory特定のカテゴリーの書籍を検索し、検索結果を返す
SearchBooks
ByCategoryRequest
category文字列カテゴリー名
start整数結果開始位置
lines整数結果行数
SearchBooksResponseresult SearchBooks
Result
検索結果
getBookByISBNISBN番号を使って書籍情報を取り出す
GetBookByISBNRequestisbn文字列ISBN番号
GetBookByISBNResponsebookinfoBookInfo書籍情報

表8.書店インターフェース
ポート型名「 BookStore
操作名   メッセージ名メッセージ内容説明
order書籍を注文する
OrderRequestbookorderBookOrder書籍注文データ
OrderResultorderresultOrderResult注文結果データ



上に戻る


プログラミング・インターフェースで定義してみる

おいおい、抽象インターフェースじゃなかったのか?と抗議されそうですが、まずはプログラマの人に一番簡単なプログラミング・インターフェースからいきましょう。SOAの抽象インターフェースは、プログラミング言語でも定義することができます。

Javaで実装してみます。Javaでは以下のようなルールで作ります。

  1. データは、Serializable インターフェースを実装したデータクラスとし、アクセサを定義する
  2. ポート型の単位でインターフェース・クラス(interface)を定義し、メソッドからはRemoteException がスローされることを宣言する。このインターフェース・クラスを「 エンドポイント・インターフェース 」と呼びます。
  3. 文字列はString、整数はintといったプリミティブ型で定義する

上のデータ型とインターフェースをを定義したものがソースコード1です。行数の関係から、BookInfoとBookSearcherのみを掲載しています。


ソースコード1.Javaによるインターフェース定義
                
package com.yone.soa.book;
import java.io.Serializable;

public class BookInfo implements Serializable {
    private static final long serialVersionUID = -4277334378818084483L;
    private String title;
    private String subtitle;
    private String author;
    private String publisher;
    private String isbn;
    private String picture;
    private int price;
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getIsbn() {
        return isbn;
    }
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
    public String getPicture() {
        return picture;
    }
    public void setPicture(String picture) {
        this.picture = picture;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public String getPublisher() {
        return publisher;
    }
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }
    public String getSubtitle() {
        return subtitle;
   }
    public void setSubtitle(String subtitle) {
        this.subtitle = subtitle;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
}


package com.yone.soa.book.service;

import java.rmi.RemoteException;
import com.yone.soa.book.BookInfo;
import com.yone.soa.book.SearchBooksResult;

public interface BookSearcher {
    public String
       getCategories(String initial)
       throws RemoteException;
    public SearchBooksResult
       searchBooksByCategory(String category)
       throws RemoteException;
    public BookInfo
       getBookByISBN(String isbn)
       throws RemoteException;
}

業務アプリケーションに携わる人は、このプログラムコードにアクセスするのはとても簡単でしょう。標準的なJavaの文法を知っているだけでプログラミングが可能なはずです。

ソースファイルを含むZIPファイルが こちら からダウンロードできます。




上に戻る


XMLから定義する

では、WSDLでこの抽象インターフェースを定義してみましょう。テキスト・エディターを使ってWSDLを書くのは大変なので、WSDL専用のエディターを使います。ここではRAD(RationalApplication Developer for WebSphere)に搭載されているWSDLエディターを使います。

このやりかたでは二つのステップで行います。それは、XMLスキーマ・データ型(XSDファイル)を作ることと、WSDLを作ることです。XMLスキーマは、これまた最初から作ると大変なので、サンプルXMLを作ってそこから生成しましょう。

サンプルになるXMLファイルを作る

RAD上のプロジェクト(なんでもかまいません)にとりあえずWSDLとかいう名前のフォルダーを作ってください。そして、フォルダー上で右クリックし、「新規」-「その他」を選択し、「すべてのウイザードを表示」にチェックを入れて、「XML」-「XML」を選択します。ウィザードで「XMLファイルを最初から作成」にチェックを入れて「次へ」ボタンをクリックします。


図1. XMLファイルの作成
図1. XMLファイルの作成

ファイル名に「BookInfo」を入力して「終了」ボタンをクリックします。


図2. XMLファイル名の指定

空のXMLファイルが開きますので、書籍情報にあたるXMLがどんなカタチになるかを示すために、次のように書き込みます。

<?xml version="1.0" encoding="UTF-8"?>
<BookInfo>
<title>aaaa</title>
<subtitle>bbbb</subtitle>

<author>cccc</author>
<publisher>dddd</publisher>
<isbn>eeee</isbn>
<picture>fffff</picture>
<price>1234</price>

</BookInfo>

エディターを閉じて(Ctrl+F4)保存します。

XMLスキーマを生成する

今作ったファイルを右クリックして、「生成]-「XMLスキーマ」を選択します。ファイル名はきっと「BookInfo.xsd」となります。「終了」ボタンをクリックしてください。「XMLスキーマが正常に生成されました。」と出力されればうまくいってます。

さて、ここですこし調整しなければなりません。最初にすべきなのは接頭部と名前空間を与えることです。ここでは、便宜上、接頭語「Q1」、名前空間を「http://www.yone.com/xsd/books」とします。


図3. 接頭部と名前空間の指定

アウトライン・ビューを見てください。なにもしないと、すべての要素が文字列データとなります。しかし、price要素だけは整数に変更しなければなりませんね。そこで、アウトライン・ビューの「エレメント」-「price」をクリックして選択し、プロパティー・ビューを見てください。「型」というところに「xsd:string」と表示されていますね。その右側の



マークをクリックして、「組み込み単純型」の「xsd:int」を選択してください。


図4. 型の指定


図5. int型に変更したところ

同様の方法で、他のスキーマも作成します。BookInfo、SearchBooksResultItem、Customer、BookOrderItemはプリミティブ型のみでできているので同じ手順で作れます。接頭語、名前空間は同じもので結構です。

さて、他のスキーマを取り込み、配列であるものはどうしましょうか。たとえば、SearchBooksResultがそうです。これに関しては次のようにサンプルを作ってXSDを生成します。

<?xml version="1.0" encoding="UTF-8"?>

<SearchBooksResult>
<resulttotal>1</resulttotal>
<results>
<SeachBooksResultItem></SeachBooksResultItem>
<SeachBooksResultItem></SeachBooksResultItem>
<SeachBooksResultItem></SeachBooksResultItem>

<SeachBooksResultItem></SeachBooksResultItem>
</results>
</SearchBooksResult>

次に、XSDから別のXSDを参照させなければいけません。XSDを生成してXSDエディターが開いたら接頭語と名前空間を設定します。次にアウトライン・ビューの「ディレクティブ」を右クリックし、「インポートの追加」を選択します。すると、<import>タブが追加されます。アウトライン上には「ロケーション(位置のこと)が指定されていません」と表示されていますので、それを選択し、プロパティー・ビュー上でスキーマ位置の右側のボタンをクリックして「ワークベンチ・プロジェクト」から、先に作成した「SearchBooksResultItem.xsd」を選択します。

注:インクルードは同じ名前空間の場合、インポートは違う名前空間の場合に指定します。

このままだと、SearchBooksResultItemが、前のファイルとこのファイルの両方に存在してしまいます。最後にアウトライン・ビューから、SearchBooksResultItemのエレメントを削除します。


図6. 重複エレメントを削除する

これで終了です。SearchBooksResult.xsdは、SearchBooksResultItem.xsdを参照しており、itemsのしたには、配列が入ります。カテゴリーの配列も同じように作成しておく必要があります。CategoryArrayの下にcategoryが並ぶように作成してください。

同じやりかたでBookOrder.xsdを作ります。

WSDLを作る

すべてのデータ項目のXMLサンプルとXSDファイルを作成したら、WSDLの作成にとりかかります。今度は、新規ファイルとして「Webサービス」-「WSDL」を選択します。「BookSearcher.wsdl」と名前をつけましょう。

WSDLエディターの基本は、各区画ごとに「右クリックして追加」を繰り返していくことです。すでに、リクエスト-レスポンス型の操作が定義されていますので、これをそのまま使います。

XSDを参照する定義を加えます。「インポート」の区画で右クリックし、インポートの追加を選択して、BookInfo、BookSearchResultを追加します。


図7. インポートの追加

あとは、右下のポートタイプとメッセージの区画での作業となります。既存のものは、クリックしてプロパティー・ビューで名前などを調整します。メッセージに関しては、正しい型を指すように変更します。ポート・タイプ上に操作を追加し、同じ作業を繰り返します。

出来上がったファイルのgetBookByISBNResponseと、searchBooksByCatagoryの部分を展開した表示を掲載します。


図8. BookInfo部分


図9. SearchBooksResult部分

これで完成です。ここまで作業したWSDLファイルは こちら からダウンロードできます。

今回解説したように、抽象インターフェースはJava言語や、XMLスキーマとともにWSDLなどで定義することができます。 WSDLで定義したインターフェースをもとに、Webサービスを作る手順が こちらに あります。



著者について

1987年に日本アイ・ビー・エム入社。メインフレームOS、ミドルウェアの障害対応、障害解析ソフトウェアの開発、ワークフローシステム開発、オブジェクト指向開発、Web開発など経験。2000年より、ソフトウェアのテクノロジーエバンジェリストとして活動中。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



はいいいえわからない
 


 


54321
大変素晴らしい不充分・不完全である
 


上に戻る


    日本IBMについて プライバシー お問い合わせ