Eclipseを使用したJavaにおけるSOAPウェブサービスの例

JavaでSOAP Webサービスを開発する方法はいくつかあります。前回のチュートリアルでは、JAX-WS SOAP Webサービスについて学びましたが、今日はEclipseを使用してSOAPウェブサービスとそのクライアントプログラムを作成する方法を学びます。ここではJAX-WSを使用せず、Eclipseに統合されているApache Axisを使用し、アプリケーションをJava Webサービスに変換し、テスト目的のクライアントスタブとテスト用JSPページを簡単かつ迅速に作成します。

JavaでのSOAP Webサービス

このチュートリアルでは、Eclipse Mars Release(4.5.0)を使用していますが、古いバージョンのEclipseでもこれらの手順が機能すると思います。また、Apache Tomcatや他のサーブレットコンテナをEclipseのサーバーとして追加していることを確認してください。それでは、EclipseでのWebサービスの実装を始めましょう。

SOAPウェブサービスの例

EclipseでのSOAPウェブサービスの例を始めましょう。まずは、アプリケーションのビジネスロジックを含むシンプルなDynamic Web ProjectをEclipseで作成します。上部の「次へ」ボタンをクリックすると、次のページに進み、ウェブプロジェクトの名前とターゲットランタイムを入力することができます。私はApache Tomcat 8を使用していますが、他の標準的なサーブレットコンテナを使用することもできます。次をクリックすると、「コンテキストルート」と「コンテンツディレクトリの場所」を指定するように求められますが、デフォルトのままにしておいてください。最後に「完了」をクリックすると、Eclipseがプロジェクトの骨組みを作成します。さあ、ビジネスロジックを始めましょう。例えば、オブジェクトの追加、削除、取得ができるウェブサービスを公開したいとします。最初のステップは、モデルビーンを作成することです。

package com.scdev.jaxws.beans;

import java.io.Serializable;

public class Person implements Serializable{

	private static final long serialVersionUID = -5577579081118070434L;
	
	private String name;
	private int age;
	private int id;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	@Override
	public String toString(){
		return id+"::"+name+"::"+age;
	}

}

上記はシンプルなJavaビーンであることに注意してください。このJavaビーンはネットワーク上で転送されるため、Serializableインターフェースを実装しています。また、このオブジェクトをクライアント側で表示する際に使用されるtoStringメソッドの実装も提供しています。次のステップはサービスクラスを作成することで、PersonServiceというインターフェースとそのシンプルな実装クラスPersonServiceImplが作成されます。

package com.scdev.jaxws.service;

import com.scdev.jaxws.beans.Person;

public interface PersonService {

	public boolean addPerson(Person p);
	
	public boolean deletePerson(int id);
	
	public Person getPerson(int id);
	
	public Person[] getAllPersons();
}

以下は、実装サービスクラスです。データソースとしてPersonオブジェクトを保持するために、Mapを使用しています。実際のプログラミングでは、これらをデータベーステーブルに保存したいと考えています。

package com.scdev.jaxws.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.scdev.jaxws.beans.Person;

public class PersonServiceImpl implements PersonService {

	private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
	
	@Override
	public boolean addPerson(Person p) {
		if(persons.get(p.getId()) != null) return false;
		persons.put(p.getId(), p);
		return true;
	}

	@Override
	public boolean deletePerson(int id) {
		if(persons.get(id) == null) return false;
		persons.remove(id);
		return true;
	}

	@Override
	public Person getPerson(int id) {
		return persons.get(id);
	}

	@Override
	public Person[] getAllPersons() {
		Set<Integer> ids = persons.keySet();
		Person[] p = new Person[ids.size()];
		int i=0;
		for(Integer id : ids){
			p[i] = persons.get(id);
			i++;
		}
		return p;
	}

}

私たちのビジネスロジックはこれで終了です。これらをウェブサービスで使用するため、ここでウェブページを作成する意味はありません。上記のコードには何らかのウェブサービスクラスへの参照がないことに注意してください。

Eclipseを使用してJavaでのSOAPウェブサービス

ビジネスロジックの準備が整ったら、次のステップはEclipseを使用してウェブサービスアプリケーションを作成することです。新しいプロジェクトを作成し、ウェブサービスウィザードを選択してください。次のボタンをクリックすると、ウェブサービスとそのクライアントの詳細を入力するページが表示されます。このページはウェブサービスの作成において最も重要です。必ず「Webサービスの種類」を「ボトムアップのJavaビーンウェブサービス」と選択してください。なぜなら、ボトムアップアプローチで実装するからです。ウェブサービスを作成する方法は2つあります。

    1. コントラクト最後またはボトムアップアプローチ:このアプローチでは、まず実装を作成し、それからその実装からWSDLファイルを生成します。私たちの実装はこのカテゴリに適合します。

 

    コントラクト最初またはトップダウンアプローチ:このアプローチでは、最初にWebサービスのコントラクト、つまりWSDLファイルを作成し、それからその実装を作成します。

サービスの実装では、完全に分類されたクラスパスで実装クラス(PersonServiceImpl)を提供してください。サービスとクライアントのタイプのスライダーを左側に移動して、クライアントプログラムとWebサービスをテストするためのUIを生成できるようにしてください。Webサービスの実装での設定を確認し、サーバランタイム、Webサービスランタイム、およびサービスプロジェクトの正しい詳細を提供してください。通常、これらは自動的に入力され、ここで変更は必要ありません。クライアントの設定では、クライアントプロジェクト名を任意の名前で指定できます。デフォルトはSOAPExampleClientになっています。Webサービスランタイムのリンクをクリックすると、以下のイメージに示されているように、さまざまなオプションを選択することができます。ただし、デフォルトのままにしています。次のボタンをクリックすると、Webサービスとして公開するメソッドを選択できます。また、ドキュメントスタイルまたはリテラルスタイルでのWebサービススタイルも選択できます。WSDLドキュメント名を変更することもできますが、後で混乱を避けるために実装クラス名としておくと良いでしょう。次のボタンをクリックすると、サーバの起動ページが表示され、[サーバを開始]ボタンをクリックして、次のボタンを有効にします。次のボタンをクリックすると、「Webサービスエクスプローラー」を起動するページが表示されます。[起動]ボタンをクリックすると、ブラウザの新しいウィンドウが開き、クライアントアプリケーションの前にWebサービスをテストすることができます。私たちのプロジェクトでは以下のイメージのようになります。ここでいくつかのサニティテストを行うこともできますが、私たちのシンプルなアプリケーションでは、クライアントアプリケーションの作成に進む準備ができています。EclipseのWebサービスポップアップウィンドウで[次へ]ボタンをクリックすると、クライアントアプリケーションのソースフォルダーを選択するページが表示されます。[次へ]ボタンをクリックすると、テスト施設として選択するさまざまなオプションが表示されます。私はJAX-RPC JSPsを選択して、クライアントアプリケーションが使用できるJSPページを生成します。getEndpoint()メソッドとsetEndpoint(String)メソッドが追加されることに注意してください。これらを使用してWebサービスのエンドポイントURLを取得し、サーバを別のURLエンドポイントに移動する場合に別のURLに設定することができます。[完了]ボタンをクリックすると、Eclipseはワークスペースにクライアントプロジェクトを作成し、以下に示すようにクライアントテストJSPページを起動します。お好きなブラウザでURLをコピーして開くことができます。公開したいサービスのテストを行い、出力を確認してみましょう。

エクリプスSOAP Webサービスのテスト

  • addPerson
  • getPerson
  • getAllPersons Notice that Person details are not printed in the results section, this is because it’s auto generated code and we need to refactor it a little to get the desired output. Open Result.jsp in the client project and you will see it’s using switch case to generate the result output. For getAllPersons() method, it was case 42 in my case. Note that it could be totally different in your case. I just changed the code for case 42 as shown below.
    case 42:
    gotMethod = true;
    com.scdev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons();
    if(getAllPersons42mtemp == null){
    %>
    <%=getAllPersons42mtemp %>
    <%
    }else{
    String tempreturnp43 = null;
    if(getAllPersons42mtemp != null){
    java.util.List listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp);
    //tempreturnp43 = listreturnp43.toString();
    for(com.scdev.jaxws.beans.Person p : listreturnp43){
    int id = p.getId();
    int age = p.getAge();
    String name=p.getName();
    %>
    <%=id%>::<%=name %>::<%=age %>
    <%
    }
    }
    }
    break;After that we get below output, note that Eclipse is doing hot deployment here, so I didn’t had to redeploy my application.

ウェブサービスとクライアントアプリケーションは正常に動作しているようですね。Eclipseによって生成されたクライアント側スタブにもっと理解を深めるために時間をかけるようにしてください。

SOAP WebサービスのWSDLと設定

最後に、以下のようにWSDLファイルがWebサービスプロジェクトに生成されることに気付くでしょう。PersonServiceImpl.wsdlコード:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.scdev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.scdev.com" xmlns:intf="https://service.jaxws.scdev.com" xmlns:tns1="https://beans.jaxws.scdev.com" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
 <wsdl:types>
  <schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.scdev.com" xmlns="https://www.w3.org/2001/XMLSchema">
   <import namespace="https://beans.jaxws.scdev.com"/>
   <element name="addPerson">
    <complexType>
     <sequence>
      <element name="p" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
   <element name="addPersonResponse">
    <complexType>
     <sequence>
      <element name="addPersonReturn" type="xsd:boolean"/>
     </sequence>
    </complexType>
   </element>
   <element name="deletePerson">
    <complexType>
     <sequence>
      <element name="id" type="xsd:int"/>
     </sequence>
    </complexType>
   </element>
   <element name="deletePersonResponse">
    <complexType>
     <sequence>
      <element name="deletePersonReturn" type="xsd:boolean"/>
     </sequence>
    </complexType>
   </element>
   <element name="getPerson">
    <complexType>
     <sequence>
      <element name="id" type="xsd:int"/>
     </sequence>
    </complexType>
   </element>
   <element name="getPersonResponse">
    <complexType>
     <sequence>
      <element name="getPersonReturn" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
   <element name="getAllPersons">
    <complexType/>
   </element>
   <element name="getAllPersonsResponse">
    <complexType>
     <sequence>
      <element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
  </schema>
  <schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.scdev.com" xmlns="https://www.w3.org/2001/XMLSchema">
   <complexType name="Person">
    <sequence>
     <element name="age" type="xsd:int"/>
     <element name="id" type="xsd:int"/>
     <element name="name" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

   <wsdl:message name="addPersonResponse">

      <wsdl:part element="impl:addPersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getAllPersonsResponse">

      <wsdl:part element="impl:getAllPersonsResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="deletePersonResponse">

      <wsdl:part element="impl:deletePersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="addPersonRequest">

      <wsdl:part element="impl:addPerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getPersonResponse">

      <wsdl:part element="impl:getPersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getPersonRequest">

      <wsdl:part element="impl:getPerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="deletePersonRequest">

      <wsdl:part element="impl:deletePerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getAllPersonsRequest">

      <wsdl:part element="impl:getAllPersons" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:portType name="PersonServiceImpl">

      <wsdl:operation name="addPerson">

         <wsdl:input message="impl:addPersonRequest" name="addPersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:addPersonResponse" name="addPersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="deletePerson">

         <wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getPerson">

         <wsdl:input message="impl:getPersonRequest" name="getPersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:getPersonResponse" name="getPersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getAllPersons">

         <wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest">

       </wsdl:input>

         <wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse">

       </wsdl:output>

      </wsdl:operation>

   </wsdl:portType>

   <wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl">

      <wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>

      <wsdl:operation name="addPerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="addPersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="addPersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="deletePerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="deletePersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="deletePersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getPerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="getPersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="getPersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getAllPersons">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="getAllPersonsRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="getAllPersonsResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

   </wsdl:binding>

   <wsdl:service name="PersonServiceImplService">

      <wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl">

         <wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl"/>

      </wsdl:port>

   </wsdl:service>

</wsdl:definitions>

Eclipseでデザインモードで開くと、下の画像のようになります。また、Webサービスのエンドポイントに?wsdlを追加することで、ブラウザからもWSDLファイルにアクセスできます。さらに、web.xmlも変更され、WebサービスのフロントコントローラーとしてApache Axisが使用されることにも気づくでしょう。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SOAPExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <display-name>Apache-Axis Servlet</display-name>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/servlet/AxisServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
  <servlet>
    <display-name>Axis Admin Servlet</display-name>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
    <load-on-startup>100</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/servlet/AdminServlet</url-pattern>
  </servlet-mapping>
</web-app>

以下の画像は、ウェブサービスとクライアントプロジェクトを示しています。すべての自動生成スタブとJSPページによってウェブサービスをテストすることができます。これがEclipseを使用したJavaのSOAPウェブサービスの例です。Eclipseが自動的に難しい部分をすべて処理してくれるため、私たちの焦点はウェブサービスのビジネスロジックを記述することです。

コメントを残す 0

Your email address will not be published. Required fields are marked *