SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

カスタムな型定義を含むWSDL文書をJavaで扱う方法

XMLBeansを利用してXMLスキーマからJavaのクラスとインターフェイスを生成する

  • X ポスト
  • このエントリーをはてなブックマークに追加

既定のWSDL型システムやエンコーディングでは自作アプリケーションのニーズを満たせない場合はどうしたらよいでしょうか。心配は無用です。この問題は、カスタムのデータ型とエンコーディング形式をJavaと組み合わせれば解決できます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 今日ではWebサービスのメッセージングやXMLベースのデータ転送が大量に行われているため、これらのメッセージ交換を構造化された方法で表現する必要性が出てきています。この必要性をふまえて開発されたのがWebサービス記述言語(Web services Description Language:WSDL)です。WSDLは、Webサービスを関連メッセージの交換を行うエンドポイント群として記述するためのXML文法を定義しています。WSDL文書はWebサービスを記述するための標準的な手段であり、Webサービスで使用されるデータ型や、そのWebサービスの通信相手となるURL、Webサービスの名前などを定義します。

 WSDL文書は、B2Bの相互運用性を実現するための重要な鍵になりつつあります。WSDL文書では、Webサービスの開発に使用したプログラミング言語の種類に関係なく、汎用的なWebサービス記述を行うことができます。開発者はWSDL文書に基づいて、対応するWebサービスと通信するクライアントコードを生成できます。このような汎用的な形式のサービス/コンポーネント記述という手法は、過去にもさまざまなバイナリ形式のインターフェイス記述言語(Interface Description Languages:IDL)という形で試みられてきましたが、WSDLとWebサービスという組み合わせほど普及したものは今までありませんでした。

 WSDLベースのサービス記述が成功した1つの理由は、XMLの普及と、実質的にどんなプログラミング言語のどんなデータ型でも汎用的な方法で定義できるというXMLの能力にあります。この記事では、Javaプログラミング言語でカスタムWSDLデータ型を扱う方法について説明します。

WSDLの概要

 WSDL文書とは、Webサービスをメッセージ対応またはプロシージャ指向の抽象的なエンドポイント群として記述するXML文書です。これらの操作やメッセージと、それに関連するデータ型は概念的に記述され、その後、必要に応じてネットワークプロトコル、メッセージ形式、プログラミング言語へと具体的にバインドされます。

 WSDL文書では、Webサービスを記述するために次の要素を定義します。

  • types……データ型定義
  • message……転送されるデータの抽象定義
  • operation……サービスプロシージャの抽象記述
  • portType……1つまたは複数のエンドポイントでサポートされる抽象操作の集まり
  • binding……特定のポートタイプに対する具体的なプロトコルとデータ形式
  • port……バインディングおよびネットワークアドレスとして定義される1つのエンドポイント
  • service……関連するエンドポイントまたはポートの集まり

WSDLとデータ型

 Webサービスプロバイダにとっては、非常に幅広い範囲のWebサービスコンシューマに理解してもらえるデータ型システムを公開することは難しい課題です。しかし、効果的な通信を行うためには、Webサービスのコンシューマとプロバイダの双方がデータ型システムを理解していることが不可欠です。各種のプログラミング言語にはそれぞれ独特の表現方法があるため、共通のデータ型システムを作成することが最重要課題になります。

 汎用的なIDLや、COM、DCOM、CORBAなどの共通データ型システムといった以前の試みとは異なり、WSDLでは、共通データ型の問題を解決するために、すべてを包含するデータ型標準を作成するのではなく、最大限の柔軟性を実現するという方法を採用しています。つまり、WSDLは1つのデータ型システムにバインドされるものではありません。その代わりに、W3CのXML Schema仕様を基準の型システムとして推奨しており、この非常に広い範囲で使われているデータ型システムを既定のものとして扱っています。

WSDLとXML Schema仕様

 WSDLの型定義には任意のエンコーディング形式を使用できますが、WSDLの仕様では、XML Schema Definitions(XSD)を使用することが推奨されています。XSDまたはXML Schemaは、XML文書内の構造を定義するための文書型定義(Document Type Definition:DTD)標準を置き換えることを意図して定められたW3C標準です。XML Schemaでは、プログラミング言語に依存しない、包括的な一連のプリミティブ/単純データ型が定義されており、doublestringintegerなどに加えて、事前定義された単純型を用いて複雑な型を作成するメカニズムも定義されています(表1を参照)。

表1 XML Schemaの単純データ型:XSDで事前定義されている単純型の一覧
単純型
stringThis is a string
normalizedStringThis is a normalized string
tokenThis is a token
base64BinaryGpM7
hexBinary0FB7
integer-1、0、103
positiveInteger1、2、215
negativeInteger-563、-2、-1
nonNegativeInteger0、1、2、672
nonPositiveInteger-37 -2、-1、0
long-9223372036854775808、... -1、0、1、... 9223372036854775807
unsignedLong0、1、... 18446744073709551615
int-2147483648、... -1、0、1、... 2147483647
unsignedInt0、1、...4294967295
short-32768、... -1、0、1、... 32767
unsignedShort0、1、... 65535
byte-128、...-1、0、1、... 127
unsignedByte0、1、... 255
decimal-1.23、0、123.4、1000.00
float-INF、-1E4、-0、0、12.78E-2、12、INF、NaN
double-INF、-1E4、-0、0、12.78E-2、12、INF、NaN
booleantrue、false、1、0
durationP1Y2M3DT10H30M12.3S
dateTime1999-05-31T13:20:00.000-05:00
date1999-05-31
time13:20:00.000、13:20:00.000-05:00
gYear1999
gYearMonth1999-02
gMonth-05
gMonthDay-05-31
gDay--31
NameshipTo
QNamepo:USAddress
NCNameUSAddress
anyURIhttp://www.example.com/,http://www.example.com/doc.html#ID5
languageen-GB、en-US、fr

 WSDLの<types>要素では、WebサービスコンシューマとWebサービスプロバイダの間で交換されるデータ型を定義します。WSDL文書で定義されるWebサービスが組み込みのXML Schema単純型のみを使用している場合は、<types>要素を含める必要はありません。一方、独自の型を使用する場合は、この要素を使用して定義できます。リスト1に、<types>要素を含んだ単純なWSDL文書を示します。

リスト1 型定義を含む単純なWSDL文書
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions 
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns="http://schemas.xmlsoap.org/wsdl/">

   <wsdl:types>
      <schema xmlns="http://www.w3.org/2001/XMLSchema"
              targetNamespace="urn:helloworld">
         <import namespace=
            "http://schemas.xmlsoap.org/soap/encoding/"/>

         <complexType name="HelloWorld">
            <sequence>
               <element name="message"
                        type="string"
                        minOccurs="1"/>
            </sequence>
         </complexType>
      </schema>
   </wsdl:types>

   <wsdl:message name="HelloWorldResponse">
      <wsdl:part name="return"
                 type="HelloWorld"/>
   </wsdl:message>

   <wsdl:message name="HelloWorldRequest">
   </wsdl:message>

   <wsdl:portType name="HelloWorldService">
      <wsdl:operation name="HelloWorld">
         <wsdl:input name="HelloWorldRequest"
                     message="intf:HelloWorldRequest"/>
         <wsdl:output name="HelloWorldResponse"
                      message="intf:HelloWorldResponse"/>
      </wsdl:operation>
   </wsdl:portType>

   <wsdl:binding name="AxisServletSoapBinding"
                 type="intf:HelloWorldService">
      <wsdlsoap:binding
         style="rpc"
         transport=
            "http://schemas.xmlsoap.org/soap/http"/>

      <wsdl:operation name="HelloWorld">
         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="HelloWorldRequest">
            <wsdlsoap:body
               use="encoded"
               encodingStyle=
                  "http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:helloworld"/>
         </wsdl:input>

         <wsdl:output name="HelloWorldResponse">
            <wsdlsoap:body
               use="encoded"
               encodingStyle=
                  "http://schemas.xmlsoap.org/soap/encoding/"
               namespace="urn:helloworld"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>

   <wsdl:service name="HelloWorldService">
      <wsdl:port name="HelloWorldServlet"
                 binding="intf:AxisServletSoapBinding">
      <wsdlsoap:address
         location="http://127.0.0.1/services/HelloWorld"/>
      </wsdl:port>
   </wsdl:service>

</wsdl:definitions>

WSDL文書での新しいデータ型の宣言

 XML Schema仕様には、カスタムデータ型を定義するための機能が用意されています。単純なXML Schemaデータ型ではなく、抽象的な方法で表現した方が便利なデータを扱うWebサービスの場合は、その抽象的な方法をWSDLの<types>要素の中で新しいデータ型として宣言することができます。リスト1の例では、カスタムデータ型を次のように定義していました。

<complexType name="HelloWorld">
   <sequence>
      <element name="message"
               type="string"
               minOccurs="1"/>
   </sequence>
</complexType>

 この定義では、messageデータ型を単純な文字列として表しています。さらに、この新しい型定義では、minOccurs属性に0より大きな値を設定することで、この要素は必須であるという制約をデータ型に追加しています。

 カスタムデータ型のもっと洗練された使い方としては、次のようにユーザーの連絡先情報を含めるという方法が考えられます。

<complexType name="AddressType">
   <sequence>
      <element name="streetName"
               type="string"
               minOccurs="1"/>
      <element name="city"
               type="string"
               minOccurs="1"/>
      <element name="state"
               type="string"
               minOccurs="1"/>
      <element name="zip"
               type="string"
               minOccurs="1"/>
      <element name="phoneNumber"
               type="string"
               minOccurs="1"/>
   </sequence>
</complexType>

 この例の<AddressType>では、ユーザーの連絡先情報をカプセル化するカスタムデータ型を定義しています。<state>要素が単純な文字列として定義されており、その要素には実質的に、どんな長さのどんな内容のテキストも入力できるということに注目してください。堅牢性を高めたい場合は、state要素に「2文字の略称のみ受け付ける」という制約を課します。そのためには、カスタムのtwo-letter-stateデータ型を定義した後で、それを<AddressType>データ型の中で参照します。2文字に制限したカスタム文字列データ型の定義は次のようになります。

<simpleType name="two-letter-state">
   <restriction base="string">
      <length value="2"/>
   </restriction>
</simpleType>

 コード内で表現されているXSDスキーマ内のデータ型定義とJava(またはその他の言語)内のオブジェクト定義との関係は、比較的容易に見て取ることができます。マッピングソフトウェアを使用すると、この関係を明示することができます。

XSDデータ型とJavaデータ型

 Javaプログラミング言語に用意されているデータ型は、標準XSDデータ型の大部分にマッピングすることができます。表2に、XSDデータ型とJavaデータ型のマッピングを示します。

表2 XSDとJavaの型マッピング:各種のXSDデータ型と、それに対応するJavaデータ型の一覧
XSDデータ型Javaデータ型
base64Binarybyte[]
hexBinarybyte[]
booleanBoolean
byteByte
dateTimejava.util.Calendar
datejava.util.Calendar
timejava.util.Calendar
decimaljava.math.BigDecimal
doubleDouble
floatFloat
hexBinarybyte[]
intInt
unsignedShortInt
integerjava.math.BigInteger
longLong
unsignedIntLong
QNamejavax.xml.namespace.QName
shortShort
unsignedByteShort
stringjava.lang.String
anySimpleTypejava.lang.String

 表2は、単純データ型マッピングの包括的な一覧を示しています。しかし、もっと複雑な抽象化が必要で、カスタム型宣言を伴う拡張XSDデータ型が必要な場合には、Javaデータ型とのマッピングを示す表はもっと複雑になります。このようなカスタム型宣言のマッピングについて説明することがこの記事の目的ですが、その前に、マッピング操作を実装するために使うXMLツールの概要を簡単に見ておきます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
Streaming API for XML(StAX)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Jeff Hanson(Jeff Hanson)

ソフトウェア業界で18年以上の経験を持つ。これまでにWindows OpenDocポートの上級エンジニア、NovellのRoute 66フレームワークの主席設計者を務める。現在は、J2EEベースの再保険システム用のフレームワークとプラットフォームの提供を専門とするeReinsureの主任設計者。著書、執筆記事多数。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/182 2005/12/06 18:03

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング