目次


XMLBeans で Web サービス・クライアントを作成する

Comments

はじめに

Apache XMLBeans は、StAX 仕様に基づくオープン・ソースの XML と Java のバインディング・ツールです。XMLBeansを使うと、XML スキーマから Java クラスと Java インターフェースを生成できます。生成されたJava クラスは、そのスキーマに準拠する XML 文書の解析や生成に使うことができます。さらに嬉しいことに、XMLBeansでは XML を直観的に扱えるので、Java で一層簡単に XML データや文書にアクセスしたり操作したりできるようになります。

XMLBeans の XML へのアプローチとはどんなものなのか、その特徴のいくつかを検討してみましょう。

  • XMLBeans は、お馴染みの Java オブジェクト・ベースのビューで XML データを表示する一方、元のネイティブXML 構造へのアクセスを維持します。
  • XMLBeans では、文書としての XML の整合性を維持します。XML 指向の API は共通してXML を分解し、そのパーツにバインドします。XMLBeans では、XML インスタンス文書全体が1 つの単位として処理されます。XML データは XML としてメモリーに格納されます。つまり、空白文字を持つオリジナルの要素コンテンツとともに、文書の順序が保持されます。
  • スキーマから型が生成されるため、XML インスタンスへのアクセスは、JavaBeanのようなアクセサーにより、get メソッドと set メソッドで行われます。
  • XMLBeans は当初から XML スキーマを念頭に置いて設計されています。そのため、XMLBeansではすべての XML スキーマ定義がサポートされます。
  • XML に素早くアクセスします

XMLBean の開発は、XML スキーマを起点とします。XML スキーマ仕様 (「参考文献」セクションを参照)が提供する豊富なデータ・モデルでは、複雑な構造と、データに関する制約を表現することが可能です。例えば、XMLスキーマでは、文書内でのデータの順序や特定の値に関する制約を制御できます。その一例として、エントリー日付が2000 年より後でなければならないとします。Java では通常、そのようなルールを課すにはカスタム・コードが必要となりますが、XMLBeansではスキーマ制約を使うことができます。

XMLBeans 技術を使えば、WSDL ファイル内に型定義の Java クラスと Java インターフェースを生成できます。それには、WSDLTypes_To_JAVATypesクラスを実行します (「ダウンロード」セクションを参照)。このクラスの mainメソッドでは、WSDL の URL を変更する必要があります。このステップは非常に重要です。なぜならこれによって、Webサービスを起動する SOAP メッセージを作成するために使われる Java クラスとJava インターフェースが生成されるためです。WSDLTypes_To_JAVATypes クラスについての詳細は、 「WSDLに型定義の Java クラスと Java インターフェースを生成する」セクションで説明しています。

ワークスペースを XMLBeans と連動するように構成する

最初に必要なステップは、XMLBeans のバイナリー配布をダウンロードすることです。これは、apache.org の XML ページにあります。次に、アーカイブをディレクトリーに解凍します。XMLBeans 配布に含まれる.jar ファイルをプロジェクトに追加してください。

WSDL に型定義の Java クラスと Java インターフェースを生成する

XMLBeans フレームワークは、WSDL ファイルを Java オブジェクトにコンパイルするために必要なものを提供します。この機能を使って、WSDLで定義され、Web サービス・クライアントで使うことができるデータ型と関連付けたJava クラスと Java インターフェースを生成できます。WSDL 文書を動的に解釈するこの機能によって、標準の静的XML 構文解析と処理技術のより一層強力な制御を実現できます。

以下のコード・リストは、「参考文献」セクションに記載されている記事「UsingJava to Handle Custom WSDLData Types」から引用した WSDLTypes_To_JAVATypesクラス・ファイルです。このコードを見ると、WSDL ファイルで定義されたデータ型からスキーマを生成する方法が分かるはずです。

リスト 1. generateSchemas メソッド
generateSchemas(String schemadir, String classesdir,
String javasrcdir, String wsdlFileName) {
boolean doNotValidateContents = false;
XmlObject wsdlDoc = null;
MyEntityResolver myentityResolver = new MyEntityResolver();
ArrayList outerrlistener = new ArrayList();
XmlErrorWatcher errlistener = new XmlErrorWatcher(outerrlistener);
ArrayList schemalist = new ArrayList();
try {
SchemaTypeLoader loader =
XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader());
.................................       
................................
addWsdlSchemas(wsdlFileName,
(DefinitionsDocument)wsdlDoc,errlistener,doNotValidateContents,schemalist);
.................................

addWsdlSchemas メソッドでスキーマを生成し、そのスキーマを検証してから arraylistに追加します。

リスト 2. addWsdlSchemas メソッド
addWsdlSchemas(String wsdlFileName,DefinitionsDocument definitionsDocument,
XmlErrorWatcher  errlistener, boolean doNotValidateContents,ArrayList schemalist){

XmlObject[]types = definitionsDocument.getDefinitions().getTypesArray();
for (int j = 0; j < types.length; j++) {
XmlObject[] schemas = types[j].selectPath("declare namespace"
+ " xs=\"http://www.w3.org/2001/XMLSchema\""        
+ " xs:schema");
if (schemas.length == 0) {
StscState.addWarning(errlistener, "The WSDL " + wsdlFileName
+ " has no schema documents in namespace "
+ "'http://www.w3.org/2001/XMLSchema'",
XmlErrorCodes.GENERIC_ERROR,definitionsDocument);
continue;
}
for (int k = 0; k < schemas.length; k++) {
if (schemas[k] instanceof SchemaDocument.Schema) {
SchemaDocumentImpl.SchemaImpl schemaImpl = (SchemaDocumentImpl.SchemaImpl) schemas[k];
System.out.println ("Validating schema...");
if (schemaImpl.validate(opts)) {
System.out.println("Schema passed validation");
schemalist.add(schemas[k]);
}else {
System.out.println("Schema failed validation");
schemalist.add(schemas[k]);
}
}

compileSchema メソッドと generateJavaSource メソッドで、生成されたスキーマのコンパイルとJava ファイルの生成をそれぞれ行います。最後に、CompileJavaSource メソッドでJava ソース・ファイルをコンパイルします。

リスト 3. compileSchemas、generateJavaSource、および CompileJavaSourceメソッド
SchemaTypeSystem compileSchemas(String schemadir,ArrayList schemalist, MyEntityResolver 
myentityResolver,XmlErrorWatcher errlistener) 
{
SchemaDocument.Schema[] sdocs = (SchemaDocument.Schema[]) schemalist
.toArray(new SchemaDocument.Schema[schemalist.size()]);
ResourceLoader cpResourceLoader = null;
SchemaTypeLoader linkTo = SchemaTypeLoaderImpl.build (null, cpResourceLoader, null);.
.................
.................
SchemaTypeSystem sts = SchemaTypeSystemCompiler.compile (params);
....................


generateJavaSource(String classesdir,String javasrcdir, SchemaTypeSystem sts) {
File classesDir = new File(classesdir);
File srcDir = IOUtil.createDir(new File("."), javasrcdir);

// now, generate the source files
XmlOptions options = new XmlOptions();
boolean verbose = false;
boolean incrSrcGen = false;
Repackager repackager = null;
FilerImpl filer = new FilerImpl(classesDir, srcDir, repackager,
verbose, incrSrcGen);

System.out.println ("Generating Java source...");
if (SchemaTypeSystemCompiler.generateTypes(sts, filer, options)) {
............................
...............................

CompileJavaSource(List sourceFiles, String classesDirName) {
File classesDir = new File(classesDirName);
boolean debug = false;
System.out.println ("Compiling Java source files...");
If (CodeGenUtil.externalCompile (sourceFiles, classesDir, null, debug)) {       
..................
..................

Web サービスのクライアントを作成する

XMLBeans を使って Web サービスのクライアントを作成するには、SOAP メッセージを直接作成し、そのSOAP メッセージを Web サービス URL に送ります。

SOAP メッセージを作成する

  • ステップ 1. 以下を呼び出して SOAPMessaage インタスタンスを作成します。 SOAPMessage smsg =MessageFactory.newInstance ().createMessage ()
  • ステップ 2. SOAP エンベロープと本体を作成します。 SOAPPart prt = smsg.getSOAPPart ();
    SOAPEnvelope env = prt.getEnvelope ();
    SOAPBody bdy = env.getBody ();
  • ステップ 3. メソッドの入力タイプに合わせてクラスをインスタンス化します。 GetPlacedOrderDocument Placedorderdoc=GetPlacedOrderDocument.Factory.newInstance();
    GetPlacedOrderDocument.GetPlacedOrder order=placedorderdoc.addNewGetPlacedOrder();
    Customer customer=order.addNewCust ();
    customer.setId (835163);
    customer.setFname ("Jerry");
    customer.setLname ("tukker");
    customer.setLocation ("abcd..");
  • ステップ 4. 上記のクラス・インスタンスを SOAP メッセージの本体に追加します。 Node nd= placedorderdoc.getDomNode ();
    SOAPBodyElement ele = bdy.addDocument ((Document) nd);
  • ステップ 5. SOAP メッセージを Web サービスのエンド・ポイントに送信します。 URL endpoint = new URL ("http://localhost:9080/Sample/services/SampleWebService");
    SOAPMessage response = con.call (smsg, endpoint);

上記のステップが完了すると、以下のコード・リストになります。

リスト 4. SOAP クライアント
MessageFactory mfact = MessageFactory.newInstance();
SOAPMessage smsg = mfact.createMessage();

SOAPPart prt = smsg.getSOAPPart();
SOAPEnvelope env = prt.getEnvelope();
SOAPBody bdy = env.getBody();

GetPlacedOrderDocument placedorderdoc=GetPlacedOrderDocument.Factory.newInstance();
GetPlacedOrderDocument.GetPlacedOrder order=placedorderdoc.addNewGetPlacedOrder();
Customer customer=order.addNewCust();
customer.setId(835163);
customer.setFname("Jerry");
customer.setLname("tukker");
customer.setLocation ("abcd...");
smsg.writeTo(System.out);
System.out.println();
Node nd = placedorderdoc.getDomNode();
SOAPBodyElement ele = bdy.addDocument((Document) nd); 
.............................
URL endpoint = new URL("http://localhost:9080/Sample/services/SampleWebService");

   //Send the message
SOAPMessage response = con.call(smsg, endpoint);
response.writeTo(System.out);
...........................

上記のコード・リスト GetPlacedOrderDocument は、WSDLTypes_To_JAVATypes クラスを実行した後に、(コードをテストするために使ったサンプルWeb サービスの) WSDL ファイル から生成されたインターフェースです。このWeb サービスには、Customer クラスを引数とする getPlacedOrder メソッドがあります。この Customer クラスは、idfnamelnamelocation の 4 つの属性を持ちます。

まとめ

このチュートリアルでは、XMLBeans を使って Web サービス・クライアントを作成するお手伝いをしました。作業の流れとして、まずWSDL ファイルからスキーマを生成し、これらのスキーマをコンパイルし、そして最終的に、コンパイルしたスキーマからJava ソースを生成しました。Java ソースを生成すれば、あとは簡単に SOAP メッセージを作成してWeb サービス URL に送信できます。これによって、自分で SOAP メッセージを書いたり、カスタムJava オブジェクトのシリアライゼーション/デシリアライゼーションを行う必要から解放されます。

この記事のレビューとコメントを引き受けてくださった WebSphere CommunityEdition/Geronimo L3 サポートの主任、Krishnakumar Balachandar (KK) に感謝します。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and web services
ArticleID=243759
ArticleTitle=XMLBeans で Web サービス・クライアントを作成する
publish-date=07182006