目次


Web サービスを開発する

第 1 回 Axis2 を使用して、コード・ファースト手法とコントラクト・ファースト手法で Web サービスを開発する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: Web サービスを開発する

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:Web サービスを開発する

このシリーズの続きに乞うご期待。

はじめる前に

このチュートリアルは、Web サービスを使用するアプリケーションの構築にさまざまな手法を用いている開発者を対象としています。Web サービスを使用することで、アプリケーションはその機能やメッセージをアプリケーションの外部に公開することができます。Web サービスは XML を使用してデータをエンコードまたはデコードし、(オープン・プロトコルを使用して) SOAP によってデータを転送します。

この連載について

このチュートリアルの連載では、Web サービスの基本概念について説明した後、異なる種類の SOAP エンジン (Apache Axis2、Apache CXF、JAX-WS など) を使用して Web サービスを開発する各種手法を説明します。また、SOAP メッセージに添付された大容量ファイルを送信するためのソリューションとして、MTOM (SOAP Message Transmission Optimization Mechanism) を使用する方法についても説明します。MTOM は、バイナリー・データを実際の SOAP メッセージ内で送信する代わりに、base64Binary にエンコードしてバイナリー添付ファイルとして送信します。この連載ではさらに、API として SAAJ (SOAP with Attachments API for Java) を使用してメソッドを呼び出すだけで、SOAP ベースの XML メッセージに対して読み出し/書き込みを行えること、そしてオプションでこのようなメッセージをインターネットで送受信できることを明らかにします。

第 1 回ではまず、Web サービスを支える基本概念を説明し、Axis2 で異なる手法 (コード・ファーストとコントラクト・ファースト) を適用して Web サービスを開発する方法を紹介します。

第 2 回では、JAX-WS を使用して初歩的な「Hello User」Web サービスを開発した後、レベルを 1 段上げて、JAX-WS で MTOM を使用して「File Download (ファイル・ダウンロード)」Web サービス (クライアントが Web サービスからファイルをダウンロードして、ローカルに保管することができるサービス) を開発する例を紹介します。また、SAAJ クライアントから Web サービスを呼び出す方法についても説明します。

第 3 回では、MTOM と XOP の実装をサポートする Apache CXF を利用して、「File uploading (ファイル・アップロード)」Web サービス (クライアントがファイルや添付ファイルを Web サービスにアップロードできるサービス) を開発する方法を説明します。

このチュートリアルについて

このチュートリアルの連載では、Axis2、JAX-WS、CXF などの異なる Web サービス・エンジンを使用して Web サービスを開発する方法を解説します。Web サービスを実装するには、SOAP、XML、JSON、RESTful HTTP などの各種アプリケーション・プロトコルを使用することができます。さらに Web サービスでは、HTTP や JMS (Java Message Service) などのさまざまなトランスポート・プロトコルをサポートすることができます。Web サービスを作成するには、ツールが必要です。少なくとも、何らかの SOAP 処理エンジンがなければ、受信したメッセージを構文解析したり、そのメッセージに示されている関数またはメソッドを呼び出したりすることはできません。このような処理を提供する製品は、市場に多数出回っています。これらの Web サービス開発ツールはいずれも、SOAP プロセッサーと、サーバー上で実行されているビジネス・ロジックとの間のブリッジを確立することを目的としています。一般に、サーバー上で実行されるビジネス・ロジックは、SOAP 処理ロジックとは切り離されるためです。

このチュートリアルの連載第 1 回では、Axis2 を使用してコード・ファースト (ボトムアップ) 手法で「Credit Card Validation (クレジット・カード検証)」Web サービスを開発する方法について説明し、さらに Axis2 を使用してコントラクト・ファースト (トップダウン) 手法で「Product Catalog (製品カタログ)」Web サービスを開発する方法についても説明します。

目標

このチュートリアルでは、以下の内容を学びます。

  • Web サーバー (Tomcat) をダウンロードしてインストールし (まだインストールされていない場合)、サンプル・コードを正常に実装できるようにマイナーな変更を加える方法
  • Axis2 エンジンをダウンロードしてインストールし、スタブならびにサービス・スケルトンを生成する方法
  • Web サービス (「Credit Card Validation (クレジット・カード検証)」および「Product Catalog (製品カタログ)」) を開発およびデプロイするための Axis2 ランタイム環境をダウンロードして Tomcat にインストールする方法
  • Eclipse IDE を使用して Web サービス (「Credit Card Validation (クレジット・カード検証)」) の POJO クライアントを開発する方法

前提条件

このチュートリアルでは、読者が Eclipse IDE の基本概念を十分理解していること、および Web サービス・アーキテクチャーに関する基本知識を持っていることを前提とします。

はじめに

Web サービスとは何か?

Web サービスとは、アプリケーションの機能にネットワークでアクセスできるインターフェースのことです。Web サービスは、標準的なインターネット技術を使用して作成されます。

今日インターネットにデプロイされている Web サービスは、HTML による Web サイトです。HTML による Web サイトでは、アプリケーション・サービス (コンテンツを公開、管理、検索、および取得するためのメカニズム) にアクセスするために、標準プロトコルと標準データ・フォーマット、つまり HTTP と HTML が使用されます。これらの標準に対応したクライアント・アプリケーション (Web ブラウザー) は、アプリケーション・サービスとやりとりし、本の注文や、グリーティング・カードの送信、ニュースの閲覧などのタスクを実行することができます。アプリケーション・サービスは Java で作成されている一方でブラウザーは C++ で作成されている場合や、アプリケーション・サービスは UNIX マシンにデプロイされている一方でブラウザーは Windows マシンにデプロイされている場合などでも、標準ベースのインターフェースによって抽象化されているおかげで、問題にはなりません。プラットフォームが何であろうと関係がなくなるように、Web サービスにはプラットフォーム間の相互運用性が考慮されています。相互運用性は、Web サービスの実装によって得られる主なメリットの 1 つです。Java ベースのソリューションと Microsoft Windowsベースのソリューションとの統合は、従来から難しい課題となっていますが、アプリケーションとクライアントの間に Web サービス層を設けることにより、アプリケーションとクライアントの間で生じる問題を大幅に取り除くことができます。

Web サービスのメリット

非常に有名なオープン技術標準である Web サービスには、以下に挙げるようにいくつものメリットがあります。

  • ベンダー同士の競争を促進して、製品価格の低下をもたらします。
  • ある製品から別の製品への移行が容易になるため、トレーニング費用が削減されます。
  • 各ベンダー製品間での相互運用性が高まるため、保守費用が削減されます。
  • 標準の採用および長期にわたる使用がより促進されるようになります。より広くベンダーとユーザーに使用されるようになることで、より一層受け入れられる標準になります。

組織が Web サービスに移行する方法

組織が Web サービスに移行するには、主に 3 つの方法があります。その 3 つの方法とは、以下のとおりです。

  1. 新しい Web サービスをゼロから作成する (コントラクト・ファースト): 開発者がサービスの機能を作成すると同時に、これらのサービスについて記述するドキュメントを作成します。
  2. 既存の機能を Web サービスによって公開する (コード・ファースト): これは、サービスの機能がすでに存在する場合の方法です。この場合、サービスの記述を実装するだけで済みます。
  3. 他のベンダーやビジネス・パートナーの Web サービスを統合する (中間突き合わせ型): これは、別の組織によって実装されているサービスを使用したほうが、サービスをゼロから作成するよりも現実的な場合の方法です。このような場合、組織は他の組織の Web サービスや、さらにはビジネス・パートナーの Web サービスを統合することになります。

Web サービスの概念の真の有用性は、既存のアプリケーションで他の Web サービスやアプリケーションを使用できるようになる、上記 2 番目と 3 番目の方法にあります。

コード・ファースト手法とコントラクト・ファースト手法の比較

コード・ファースト (ボトムアップ) 手法では、投資したものを再利用するために、既存のアプリケーションを公開することができます。例えば、クレジット・カード・システムは、ビジネス価値が実証された既存のアプリケーションですが、競争圧力により、クレジット・カード・システムのビジネス機能の一部 (クレジット・カード番号の検証機能) が Web サービスとして公開されるようになってきています。このシステムを Web サービスとして公開するために必要なことは、実装クラスはすでに存在するので、WSDL を作成し、このクラスを Web サービスとして公開することのみです。

Web サービスをゼロから新しく作成する場合の適切な方法は、「純粋な手法」と呼ばれることが多いコントラクト・ファースト (トップダウン) 手法です。この手法は、WSDL (コントラクト) で操作メッセージなどを定義するところから始まります。その後、エンドポイント・インターフェースを作成し、最後に実装クラスを作成します。

Axis2 のアーキテクチャー

Axis2 は、コア・モジュールと非コア・モジュールからなるモジュール式アーキテクチャーをベースに作成されています。このコア・エンジンは、純粋な SOAP 処理エンジンであると考えられています (JAX-RPC の概念は一切コアに実装されていません)。したがって、システムで受信されるすべてのメッセージは、SOAP メッセージに変換してからコア・エンジンに渡す必要があります。受信されるメッセージは SOAP メッセージであることも、非 SOAP メッセージ (REST、JSON、JMX など) であることもありますが、SOAP メッセージでない場合は、トランスポート・レベルで SOAP メッセージに変換されます。Axis2 の設計時には、極めて柔軟で拡張性のある SAP 処理エンジンを実現するために、以下の主要なルールがアーキテクチャーに導入されました。

  • ステートレスな処理メカニズムを実現するために、ロジックと状態を切り離すこと (これは、Web サービスがステートレスであるからです)。
  • システムを一時停止および再開できるようにするために、単一の情報モデルにすること。
  • 今後更新される Web サービス仕様を、コア・アーキテクチャーに最小限の変更を加えるだけでサポートできるようにすること。

Apache Axis2 のアーキテクチャーは、SOAP エンジンの基礎の上に作成されています。SOAP エンジンは SOAP メッセージを受け入れて構文解析し、Web サービスの該当するメソッドと関数を呼び出します。このレベルの詳細では、Axis は他のあらゆる Web サービス・エンジンと変わりありません。この製品および他のすべての製品の独自性は、開発者が SOAP メッセージに適切に応答できる処理を構成するためにどのように取り組むかにあります。

構成と開発

例 1 ― Axis2 を使用した「Credit Card Validation (クレジット・カード検証)」Web サービス

コード・ファースト手法を使用したこの単純な「Credit Card Validation (クレジット・カード検証)」Web サービスは、ユーザーが 16 桁のクレジット・カード番号を入力すると、その番号を検証できるとともに、クレジット・カード会社を見つけられるというものです。このサンプル・アプリケーションをセットアップして実行するには、以下の知識が必要です。

Eclipse IDE: 統合開発環境 (Integrated Development Environment: IDE) とは、コンピューター・プログラムを作成、編集、コンパイル、実行するためのオール・イン・ワン・ツールのことで、なかでも Eclipse は極めて優れた統合開発環境を提供します。www.eclipse.org で、Eclipse の最新リリースを調べてください。

Tomcat Web サーバー 5.5 またはそれ以降のバージョン: Tomcat サーブレット・エンジンは、Apache Software Foundation の Jakarta プロジェクトの一部として開発されたオープンソースのパッケージであり、サーブレット仕様と JSP 仕様両方の正式なリファレンス実装です。Tomcat はスタンドアロンの Web サーバーとして機能できるだけでなく、サーブレット/JSP エンジンとしての役割を果たすこともできます。この記事を執筆した時点での Tomcat の最新リリースは、http://tomcat.apache.org/download-60.cgi からダウンロードすることができます。

Axis2:

(バイナリー・ディストリビューション): Axis2 バイナリー・ディストリビューションは、すべての関連するサード・パーティー・ライブラリー、サンプル一式、および Axis2 ランタイムからなります。バイナリー・ディストリビューションをインストールするには、zip アーカイブ・ファイルを任意の場所に解凍します。バイナリー・ディストリビューションをダウンロードして解凍すると、一連のサブディレクトリー (bin、lib、samples、repository、webapp) が含まれていることがわかります。

(WAR ディストリビューション): Axis2 WAR ディストリビューションは、Tomcat、JBoss、WebLogic などのアプリケーション・サーバーに Axis2 をデプロイする場合に便利です。Axis2 WAR ファイルをアプリケーション・サーバーにデプロイして、ブラウザーにサーバー・アドレスを入力するだけで、Axis2 が動作しているかどうかを確認することができます。例えば Axis2 WAR ファイルが Apache Tomcat にデプロイされているとしたら、ブラウザーに URL として「http://localhost:8080/axis2」を入力すると、Axis2 が稼働中であるかどうかがわかります。

Axis2 の最新リリースは、http://ws.apache.org/axis2/download.cgi からダウンロードすることができます。Axis2 の各リリースは、以下の 4 つの主要なリリース成果物 (ディストリビューション) からなります。

  • バイナリー・ディストリビューション
  • WAR ディストリビューション
  • ソース・ディストリビューション
  • JAR ディストリビューション

環境をセットアップする

  1. JDK 1.5 またはそれ以降のバージョンをシステムにインストールします。
  2. Axis2 ファイル (war バージョン) をダウンロードした後、この zip ファイルを任意のローカル・ディレクトリーに解凍します。すると、axis2.war ファイルが解凍されるので、このファイルをコピーして <TOMCAT_HOME>webapp\ ディレクトリーに貼り付けた後、Tomcat を起動してください。Tomcat の起動が完了したら、カレント・ディレクトリーを <TOMCAT_HOME>webapps\ に変更します。このディレクトリー内に、「axis2」という名前の新しいディレクトリーが作成されていれば、axis2.war ファイルが正常にデプロイされたことになります。
  3. Axis2 バイナリー・ディストリビューションをダウンロードして、任意のディレクトリーに解凍します。この解凍先のディレクトリーは <AXIS2_HOME> と呼ばれます。

CreditCardservice を開発して Tomcat にデプロイする

  1. 「Credit Card Validation (クレジット・カード検証)」Web サービス用に Axis2Example プロジェクトのディレクトリー構造 (図 1 に記載) を作成します。
図 1. Axis2Example プロジェクトのディレクトリー構造
Axis2Example プロジェクトのディレクトリー構造
Axis2Example プロジェクトのディレクトリー構造
  1. com.ibm.axis2.ccheck パッケージ内に、以下に記載する CheckSEI.java インターフェースを作成します。
リスト 1. CheckSEI.java
package com.ibm.axis2.ccheck;

import javax.jws.WebService;

@WebService (name="CheckCard",
		targetNamespace="http://ccheck.axis2.ibm.com")
		
public interface CheckSEI {
	
	public String doCheck(String targetName);
	
}
  1. 同じく com.ibm.axis2.ccheck パッケージ内に、リスト 2 に記載する CheckCard.java クラスを作成します。
リスト 2. CheckCard.java
package com.ibm.axis2.ccheck;
import javax.jws.WebService;
@WebService(serviceName = "CheckCardService",
		portName = "cport",
		endpointInterface = "com.ibm.axis2.ccheck.CheckSEI",
		targetNamespace = "http://ccheck.axis2.ibm.com")

public class CheckCard implements CheckSEI{
	
     	  public static final int INVALID          = -1;  
	  public static final int VISA             = 0;
	  public static final int MASTERCARD       = 1;
	  public static final int AMERICAN_EXPRESS = 2;
	  public static final int EN_ROUTE         = 3;
	  public static final int DINERS_CLUB      = 4;
	
	private static final String [] cardNames = 
    {   "Visa" , 
        "Mastercard", 
        "American Express", 
        "En Route", 
        "Diner's CLub/Carte Blanche",
    };

	public static boolean validCC(String number)
    throws Exception {   
    int CardID;
    if ( (CardID = getCardID(number)) != -1)
        return validCCNumber(number);
    return false;
    }

	public static boolean validCCNumber(String n) {
	    try {
	      
	      int j = n.length();
	  
	      String [] s1 = new String[j];
	      for (int i=0; i < n.length(); i++) s1[i] = "" + n.charAt(i);
	  
	      int checksum = 0;         
	    
	      for (int i=s1.length-1; i >= 0; i-= 2) {
	        int k = 0;
	        
	        if (i > 0) {
	           k = Integer.valueOf(s1[i-1]).intValue() * 2;
	           if (k > 9) {
	              String s = "" + k;
	              k = Integer.valueOf(s.substring(0,1)).intValue() + 
	                  Integer.valueOf(s.substring(1)).intValue();
	              }
	              checksum += Integer.valueOf(s1[i]).intValue() + k;            
	           }
	           else
	              checksum += Integer.valueOf(s1[0]).intValue();            
	        }
	      return ((checksum % 10) == 0);
	      }
	    catch (Exception e) {
	      e.printStackTrace();
	      return false;
	      }
	    }

	public static int getCardID(String number) {
	    int valid = INVALID;
	        
	    String digit1 = number.substring(0,1);
	    String digit2 = number.substring(0,2);
	    String digit3 = number.substring(0,3);
	    String digit4 = number.substring(0,4);
	    
	    if (isNumber(number)) {
	      
	      if (digit1.equals("4"))  {  
	        if (number.length() == 13 || number.length() == 16) 
	           valid = VISA;
	        }
	     
	      else if (digit2.compareTo("51")>=0 && digit2.compareTo("55")<=0) {
	        if (number.length() == 16) 
	           valid = MASTERCARD;
	        }
	      
	      else if (digit2.equals("34") || digit2.equals("37")) {
	        if (number.length() == 15) 
	           valid = AMERICAN_EXPRESS;
	        }
	    
	      else if (digit4.equals("2014") || digit4.equals("2149")) {
	         if (number.length() == 15) 
	            valid = EN_ROUTE;
	         }
	      
	      else if (digit2.equals("36") || digit2.equals("38") || 
	        (digit3.compareTo("300")>=0 && digit3.compareTo("305")<=0)) {
	        if (number.length() == 14) 
	           valid = DINERS_CLUB;
	           }
	      
	     	      
	      }           
	      return valid;
	      
	      
	      
	    }
	
	
	 public static boolean isNumber(String n) {
		    try  {
		      double d = Double.valueOf(n).doubleValue();
		      return true;
		      }
		    catch (NumberFormatException e) {
		      e.printStackTrace();
		      return false;
		      }
		    }

	 public static String getCardName(int id) {
		    return (id < -1 && id < cardNames.length ? cardNames[id] : "");
		    }

	
	 public String doCheck(String aCard){
		 
		 String s="";
		 boolean b;
		try{ 
		 if (getCardID(aCard) > -1) 
		 {
			  s="This is a  " + getCardName(getCardID(aCard)) + " Card .";
			if( b=validCC(aCard))
			{
				s=s+"The card number " + aCard + " is VALID " ;
			}
			else{s= s+"The card number " + aCard + " is IN-VALID " ;}
		 }
		
		 else{return("INVALID INPUT");}
		}		
		catch(Exception e){}
		 return(s);
	 }
	
	
	
}
  1. 今度は META-INF ディレクトリー内に、リスト 3 に記載する services.xml ファイルを作成します。
リスト 3. services.xml
<service>
   <description>
      This Web Service Validates CreditCard Number.
   </description>
   <parameter name="ServiceClass">com.ibm.axis2.ccheck.CheckCard</parameter>
   <operation name="doCheck">
      <messageReceiver
      class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
   </operation>   
</service>
  1. 「START (スタート)」 > 「Run (実行)」の順に選択し、「cmd」と入力して「Command Prompt (コマンド プロンプト)」を開きます。図 2 を参照してください。
図 2. 「Command Prompt (コマンド プロンプト)」を開く
「Command Prompt (コマンド プロンプト)」を開く
「Command Prompt (コマンド プロンプト)」を開く
  1. カレント・ディレクトリーを ccheck に変更し、以下のように「javac *.java」と入力します (これは、Axis2Example プロジェクトのディレクトリーから javac *.java コマンドを実行するためです。ユーザー変数 Path に <JAVA_HOME>bin\ を設定する必要があります)。
図 3. CreditCard インターフェースとクラスをコンパイルする
Compile the CreditCard interface and class
Compile the CreditCard interface and class
  1. 次に、カレント・ディレクトリーを Code First Service に変更し、以下に示すように「cvf CreditCardService.aar *」と入力して aar ファイルを生成します (図 4 を参照)。
図 4. CreditCardService.aar ファイルを生成する
CreditCardService.aar ファイルを生成する
CreditCardService.aar ファイルを生成する
  1. Tomcat を起動し、ブラウザーを開いて「http://localhost:8080/axis2」と入力し、「Administration (管理)」をクリックします。
図 5. Tomcat で Axis2 を実行する
Tomcat で Axis2 を実行する
Tomcat で Axis2 を実行する

デフォルトのユーザー名「admin」とパスワード「axis2」を入力してログインします (図 6 を参照)。

図 6. Axis2 管理コンソールにログインする
Axis2 管理コンソールにログインする
Axis2 管理コンソールにログインする
  1. ログインに成功したら、Web サービスをアップロードするためのリンクをクリックします。表示された画面で Axis2Example\Code First Service ディレクトリー内の CreditCardService.aar ファイルを参照して、(Web サービスを正常にデプロイするために)「Upload (アップロード)」をクリックします (図 7 を参照)。
図 7. CreditCardService をアップロードする
CreditCardService をアップロードする
CreditCardService をアップロードする
  1. 今度は「Available Service (使用可能なサービス)」をクリックするか、ブラウザーにリンク「http://localhost:8080/axis2/axis2-admin/listService」を貼り付けて、デプロイされた「CreditCardService」Web サービスを見つけます (図 8 を参照)。
図 8. デプロイされたCreditCardService」Web サービス
デプロイされたCreditCardService」Web サービス
デプロイされたCreditCardService」Web サービス
  1. このサービスをクリックして、http://localhost:8080/axis2/services/CheckCardService?wsdl にある「CreditCardService」Web サービスの WSDL を確認します。

スタブを生成する

  1. 「Command Prompt (コマンド プロンプト)」を開き、カレント・ディレクトリーを <AXIS2_HOME>bin| に変更して、以下のコマンドを入力します (図 9 を参照)。

wsdl2java.bat -uri http://localhost:8080/axis2/services/CheckCardService?wsdl -o client

図 9. CreditCardService のスタブを生成する
CreditCardService のスタブを生成する
CreditCardService のスタブを生成する

(<AXIS2_HOME>\bin\src\com\ibm\axis2\ccheck\ ディレクトリー内に、「CheckCardServiceCallbackHandler.java」、「CheckCardServiceStub.java」、および「ExceptionException.java」という名前でスタブが生成されているはずです)。

CreditCardService の POJO クライアントを開発する

  1. Eclipse で、「File (ファイル)」 > 「New (新規)」 > 「Java Project (Java プロジェクト)」の順 (または「File (ファイル)」 > 「New (新規)」 > 「Other (その他)」 > 「Java」 > 「Java Project (Java プロジェクト)」の順) に選択し、「Axis2Client」という名前の Java プロジェクトを作成します (図 10 を参照)。
図 10. Eclipse 内の Axis2Client Java プロジェクト
Eclipse 内の Axis2Client Java プロジェクト
Eclipse 内の Axis2Client Java プロジェクト
  1. Axis2Client\src フォルダー内に、「com.ibm.axis2.ccheck」という名前の新規パッケージを作成します (図 11 を参照)。
図 11. Axis2Client のパッケージを作成する
Axis2Client のパッケージを作成する
Axis2Client のパッケージを作成する
  1. 「Axis2Client」プロジェクトを選択して、ビルド・パスを構成します (図 12 を参照)。
図 12. Axis2Client のビルド・パスを構成する
Configure Build Path for Axis2Client
Configure Build Path for Axis2Client

「Add External JARs (外部 Jar 追加)」をクリックし、<AXIS2_HOME>lib\ 内のすべての jar ファイルを選択して「OK」をクリックします。

  1. 生成されたスタブをコピーして、Axis2Client プロジェクトの com.ibm.axis2.ccheck パッケージ内に貼り付けます (図 13 を参照)。
図 13. 生成されたスタブをコピー・アンド・ペーストする
生成されたスタブをコピー・アンド・ペーストする
  1. com.ibm.axis2.ccheck パッケージ内に、以下に記載する TestClient.java クラスを作成します。
リスト 4. services.xml
package com.ibm.axis2.ccheck;
import java.io.*;
import com.ibm.axis2.ccheck.*;

public class TestClient {
     public static void main(String[] args) throws Exception {
         CheckCardServiceStub stub = new CheckCardServiceStub();
         //Create the request

    com.ibm.axis2.ccheck.CheckCardServiceStub.DoCheck  request = new 
   com.ibm.axis2.ccheck.CheckCardServiceStub.DoCheck();
    System.out.println("Enter your Credit Card Number:");
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);
    String s = br.readLine();
    
        request.setArgs0(s);
         //Invoke the service
        com.ibm.axis2.ccheck.CheckCardServiceStub.DoCheckResponse response 
            = stub.doCheck(request);
        System.out.println(response.get_return());
    }
}
  1. 「TestClient.java」を選択して右クリックし、「Run As (実行)」 > 「Java Application (Java アプリケーション)」の順に選択します (Tomcat が稼働中であることを確認してください)。
  2. TestClient が実行中の状態になると、以下の図に示すように、コンソールにクレジット・カード番号の入力を求めるプロンプトが出されます。

    (クレジット・カード番号として、例えば「4111111111111111」と入力し、Enter キーを押すと、有効なクレジット・カード会社の名前と、入力した番号が有効であることが示されます)。
図 14. コンソールで有効なクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効であることが示される様子
コンソールで有効なクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効であることが示される様子
コンソールで有効なクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効であることが示される様子

(クレジット・カード番号として、例えば「5111111111111111」と入力し、Enter キーを押すと、有効なクレジット・カード会社の名前と、入力した番号が有効でないことが示されます)。

図 15. コンソールで有効でないクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効でないことが示される様子
コンソールで有効でないクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効でないことが示される様子
コンソールで有効でないクレジット・カード番号を入力すると、クレジット・カード会社名と、番号が有効でないことが示される様子

(クレジット・カード番号ではない「51470965」という番号を入力し、Enter キーを押すと、入力が無効であることが示されます)。

図 16. 無効な情報を入力すると、入力が無効であることが示される様子
無効な情報を入力すると、入力が無効であることが示される様子
無効な情報を入力すると、入力が無効であることが示される様子

例 2 ― Axis2 を使用したコントラクト・ファースト手法による「Product Catalog (製品カタログ)」サービスの開発

これは、コントラクト・ファースト手法で開発する非常に単純な「Product Catalog (製品カタログ)」Web サービスです。このサービスでは、ユーザーが ProductId 番号を入力して、カタログ内の目的の製品名を調べることができます。このサンプルをセットアップして実行するには、以下の知識が必要です。

Ant: Apache Ant は、互いに依存するターゲットおよび拡張ポイントとしてビルド・ファイルに記述されたプロセスを実行することをミッションとする Java ライブラリー兼コマンドライン・ツールです。Ant の主な用途として知られているのは、Java アプリケーションのビルドです。Ant には、Java アプリケーションをコンパイル、アセンブル、テスト、および実行するためのタスクが数多く組み込まれています。また Ant を効果的に使用して、Java 以外のアプリケーション (C または C++ アプリケーションなど) をビルドするために使用することもできます。一般に、ターゲットとタスクという観点で記述できるあらゆるタイプのプロセスを実行するには、Ant を使用することができます。ANT の最新リリースは、http://ant.apache.org/bindownload.cgi. からダウンロードすることができます。

環境をセットアップする

  1. ユーザー変数 Path に <ANT_HOME>bin\ を設定します (その他の環境設定はすべて、例 1 と同様です)。

WSDL を開発する

  1. <AXIS_HOME>bin\wsdl\ ディレクトリー内に、以下に記載する「product.wsdl」という名前のファイルを作成します。
リスト 5. product.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
xmlns:ns="http://contract.axis2.ibm.com" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    targetNamespace="http://contract.axis2.ibm.com">
    
        <wsdl:types>
        <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified"
targetNamespace="http://contract.axis2.ibm.com">
            <xs:element name="getProductName">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="productNumber" type="xs:int"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
                        
            <xs:element name="getProductNameResponse">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="return" nillable="true" 
                                        type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </wsdl:types>
        
    <wsdl:message name="getProductNameRequest">
        <wsdl:part name="parameters" element="ns:getProductName"/>
    </wsdl:message>
        
    <wsdl:message name="getProductNameResponse">
        <wsdl:part name="parameters" element="ns:getProductNameResponse"/>
    </wsdl:message>
        
    <wsdl:portType name="ProductPortType">
        <wsdl:operation name="getProductName">
            <wsdl:input message="ns:getProductNameRequest" 
                        wsaw:Action="urn:getProductName"/>
            <wsdl:output message="ns:getProductNameResponse" 
                        wsaw:Action="urn:getProductNameResponse"/>
        </wsdl:operation>
    </wsdl:portType>
        
    <wsdl:binding name="ProductSoap11Binding" type="ns:ProductPortType">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                          style="document"/>
        <wsdl:operation name="getProductName">
            <soap:operation soapAction="urn:getProductName" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
        
    <wsdl:binding name="ProductSoap12Binding" type="ns:ProductPortType">
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" 
                          style="document"/>
        <wsdl:operation name="getProductName">
            <soap12:operation soapAction="urn:getProductName" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
        
    <wsdl:binding name="ProductHttpBinding" type="ns:ProductPortType">
        <http:binding verb="POST"/>
        <wsdl:operation name="getProductName">
            <http:operation location="Product/getProductName"/>
            <wsdl:input>
                <mime:content type="text/xml" part="getProductName"/>
            </wsdl:input>
            <wsdl:output>
                <mime:content type="text/xml" part="getProductName"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
        
    <wsdl:service name="Product">
        <wsdl:port name="ProductHttpSoap11Endpoint" binding="ns:ProductSoap11Binding">
            <soap:address location="http://localhost:8080/axis2/services/Product"/>
        </wsdl:port>
        <wsdl:port name="ProductHttpSoap12Endpoint" binding="ns:ProductSoap12Binding">
            <soap12:address location="http://localhost:8080/axis2/services/Product"/>
        </wsdl:port>
        <wsdl:port name="ProductHttpEndpoint" binding="ns:ProductHttpBinding">
            <http:address location="http://localhost:8080/axis2/services/Product"/>
        </wsdl:port>
    </wsdl:service>
        
</wsdl:definitions>
  1. <AXIS2_HOME>|bin|wsdl2java.bat ツールを使用して、このサービスのスケルトンとその他のサポート・ファイルを作成します。
  2. 「Command Prompt (コマンド プロンプト)」を開き、カレント・ディレクトリーを <AXIS2_HOME>\bin\ に変更した上で、以下のコマンドを実行します。
    wsdl2java.bat –uri <AXIS2_HOME>\bin\wsdl\product.wsdl -d adb -s -ss -sd -ssi -o build\service
  3. このコマンドにより、<AXIS2_HOME>\bin\build\ ディレクトリー内に「service」という名前の出力が作成されます (図 17 を参照)。
図 17. 「Product Catalog (製品カタログ)」サービスのスケルトン・ディレクトリー構造
「Product Catalog (製品カタログ)」サービスのスケルトン・ディレクトリー構造
「Product Catalog (製品カタログ)」サービスのスケルトン・ディレクトリー構造

出力ターゲット・ディレクトリーの内容:

build.xml
resources\services.xml
resources\product.wsdl
src\com\ibm\axis2\contract\ExtensionMapper.java
src\com\ibm\axis2\contract\GetProductName.java
src\com\ibm\axis2\contract\GetProductNameResponse.java
src\com\ibm\axis2\contract\ProductMessageReceiverInOut.java
src\com\ibm\axis2\contract\ProductSkeleton.java
src\com\ibm\axis2\contract\ProductSkeletonInterface.java

上記に記載したファイルのうち、「src\com\ibm\axis2\contract\ProductSkeleton.java」という名前の Java ファイルに、カスタム・ビジネス・ロジック・コードを配置します。

自動生成された ProductSkeleton Java コード

リスト 6. 自動生成された ProductSkeleton.java
/**
 * ProductSkeleton.java
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: 1.5.2  Built on : Sep 06, 2010 (09:42:01 CEST)
 */
    package com.ibm.axis2.contract;
    /**
     *  ProductSkeleton java skeleton for the axisService
     */
    public class ProductSkeleton implements ProductSkeletonInterface{
     /**
         * Auto generated method signature
          * @param getProductName0
         */
        public com.ibm.axis2.contract.GetProductNameResponse getProductName
                  (
                  com.ibm.axis2.contract.GetProductName getProductName)
                 {
                
                throw new java.lang.UnsupportedOperationException("Please implement " 
                                + this.getClass().getName()
                                + "#getProductName");
        }
}

上記のクラスにビジネス・ロジックを追加して、このサービスの機能を実装します。

リスト 7. ProductSkeleton.java に追加されたビジネス・ロジック
/**
 * ProductSkeleton.java
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: 1.5.2  Built on : Sep 06, 2010 (09:42:01 CEST)
 */
 package com.ibm.axis2.contract;
import com.ibm.axis2.contract.*;
import java.util.*;
import org.apache.axis2.engine.AxisError;
    /**
     *  ProductSkeleton java skeleton for the axisService
     */
    public class ProductSkeleton implements ProductSkeletonInterface{
        private static HashMap<Integer, String> productMap   = new
HashMap<Integer, String>();
        static
        {   productMap.put(1, "Colgate");
                productMap.put(2, "Pepsodent");
                productMap.put(3, "Neem");    }
      /**
         * Auto generated method signature
          * @param getProductName0
         */      
public com.ibm.axis2.contract.GetProductNameResponse 
        getProductName ( com.ibm.axis2.contract.GetProductName getProductName)
                   {
                 /* Custom Logic - Starts here */
                int inputProductNumber = getProductName.getProductNumber();
                String productName = productMap.get(inputProductNumber);
                GetProductNameResponse response = new GetProductNameResponse();
                if (productName != null)
                {   response.set_return(productName);
                }
                else
                { throw new AxisError("Product Record Not Found");  }
               return response;
                /* Custom Logic - Ends here */
 } 
 }
  1. ここでいよいよ、この Web サービスの実装をビルドしてテストします。
  2. 「Command Prompt (コマンド プロンプト)」を開き、カレント・ディレクトリーを <AXIS2_HOME>bin\build\service\ に変更した後、以下のコマンドを実行します (以下の図を参照)。

    Ant jar.server
図 18. Ant を使用してビルドおよびテストを実行する
Ant を使用してビルドおよびテストを実行する
Ant を使用してビルドおよびテストを実行する

上記の Ant ビルドにより、<AXIS2_HOME>bin\build\service\build|lib\ 内に Product.aar ファイルが作成されます (以下の図を参照)。

図 19. Ant ビルド・ディレクトリー構造と Product.aar ファイル
Ant ビルド・ディレクトリー構造と Product.aar ファイル
Ant ビルド・ディレクトリー構造と Product.aar ファイル

Web サービスを Tomcat にデプロイする

Product.aar ファイルをデプロイする手順は、Tomcat に CreditCardService をデプロイしたときの手順と同様です。

  1. Tomcat を起動し、ブラウザーを開いて「http://localhost:8080/axis2」と入力し、「Administration (管理)」をクリックします (ログインするには、デフォルトのユーザー名「admin」とパスワード「axis2」を入力する必要があります)。
  2. ログインに成功したら、Web サービスをアップロードするためのリンクをクリックします。表示された画面で <AXIS2_HOME>bin\build\service\build\lib\ ディレクトリー内の Product.aar ファイルを参照して、(Web サービスを正常にデプロイするために)「Upload (アップロード)」をクリックします。
  3. 今度は「Available Service (使用可能なサービス)」をクリックするか、ブラウザーにリンク「http://localhost:8080/axis2/axis2-admin/listService」を貼り付けて、デプロイされた「Product」Web サービスを見つけます (以下の図を参照)。
図 20. 「Product」Web サービスのデプロイメント
「Product」Web サービスのデプロイメント
「Product」Web サービスのデプロイメント

この「Product」Web サービスの WSDL は、http://localhost:8080/axis2/services/Product?wsdl で確認することができます。

まとめ

このチュートリアルでは、Axis2 を使用して、コード・ファースト手法とコントラクト・ファースト手法の Web サービスをごく短時間で開発する方法を学びました。このチュートリアルの連載第 2 回では、JAX-WS を使用して「File Download (ファイル・ダウンロード)」Web サービスを開発し、そのサービスを SAAJ クライアントで使用する方法を学びます。


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


関連トピック

  • Apache Axis2 User's Guide」は、Apache Axis2 を初めて使用する際の出発点となるとともに、 Axis2 を使用して Web サービスを作成し、デプロイする方法などの高度なトピックについても説明しています。
  • Eclipse WTP Tutorials」に目を通してください。このチュートリアルでは、Apache Axis2 を使用したボトムアップ型 Web サービスの作成手順を説明しています。
  • SOA development with Axis2, Part 1: Understanding Axis2 basis」(developerWorks、2006年8月) で、Axis2 のアーキテクチャーについて説明しています。
  • Deliver Web services to mobile apps」(developerWorks、2003年1月) を読んでください。このチュートリアルでは、J2ME (Java 2 Platform, Micro Edition) に対応したモバイル機器で Web サービスにアクセスする方法を説明しています。
  • Sun Developer Network に掲載されている「Service-Oriented Architecture and Web Services: Concepts, Technologies, and Tools」では、Web サービスおよび SOA を対象としたツールおよび技術について説明しています。

コメント

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and web services
ArticleID=841891
ArticleTitle=Web サービスを開発する: 第 1 回 Axis2 を使用して、コード・ファースト手法とコントラクト・ファースト手法で Web サービスを開発する
publish-date=10252012