JavaのSOAP Webサービスの例(Eclipseを使用)

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

JavaでのSOAP Webサービス

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

SOAP Webサービスの例

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

package com.journaldev.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ビーンであることに注意してください。ネットワーク上で転送するために、Serializableインターフェースを実装しています。クライアント側でこのオブジェクトを印刷する際に使用されるtoStringメソッドの実装も提供しています。次に、サービスクラスを作成する必要があります。したがって、PersonServiceというインターフェースと、それに対する単純な実装クラスPersonServiceImplが存在します。

package com.journaldev.jaxws.service;

import com.journaldev.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.journaldev.jaxws.service;

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

import com.journaldev.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;
	}

}

これで私たちのビジネスロジックは完了です。これらをWebサービスで使用するため、ここでWebページを作成する意味はありません。上記のコードには、Webサービスのクラスへの参照はありません。

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

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

  1. Contract lastまたはボトムアップアプローチ:このアプローチでは、まず実装を作成し、それからWSDLファイルを生成します。私たちの実装はこのカテゴリに当てはまります。
  2. Contract firstまたはトップダウンアプローチ:このアプローチでは、まずウェブサービスの契約であるWSDLファイルを作成し、それから実装を作成します。

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

Eclipse SOAP Webサービスのテスト

  • addPerson

  • getPerson

  • getAllPersons パーソンの詳細は結果セクションに表示されません。これは自動生成コードであり、目的の出力を得るために少しリファクタリングする必要があります。クライアントプロジェクトのResult.jspを開き、結果出力にswitch caseが使用されていることがわかります。getAllPersons()メソッドの場合、私の場合はcase 42でした。ただし、あなたの場合は全く異なる場合もあります。以下に示すように、case 42のコードを変更しました。

    case 42:
            gotMethod = true;
            com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons();
    if(getAllPersons42mtemp == null){
    %>
    <%=getAllPersons42mtemp %>
    <%
    }else{
            String tempreturnp43 = null;
            if(getAllPersons42mtemp != null){
            java.util.List<com.journaldev.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp);
            //tempreturnp43 = listreturnp43.toString();
            for(com.journaldev.jaxws.beans.Person p : listreturnp43){
            	int id = p.getId();
            	int age = p.getAge();
            	String name=p.getName();
            	%>
            	<%=id%>::<%=name %>::<%=age %>
            	<%
            	}
            }
            }      
    break;
    

    その後、以下の出力が得られます。Eclipseはここでホットデプロイメントを行っているため、アプリケーションを再デプロイする必要はありません。

ウェブサービスとクライアントアプリケーションが正常に動作しているようです。さらに、Eclipseによって生成されたクライアント側のスタブを見るために時間をかけることをお勧めします。

SOAPウェブサービスのWSDLと設定

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

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.journaldev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.journaldev.com" xmlns:intf="https://service.jaxws.journaldev.com" xmlns:tns1="https://beans.jaxws.journaldev.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.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
   <import namespace="https://beans.jaxws.journaldev.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.journaldev.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を追加することで、ブラウザからもWebサービスの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>

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

Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse