第5章 Addressing のチュートリアル

このチュートリアルでは、WS-Addressing を有効にしてクライアントおよびエンドポイントの通信を作成する方法を示します。WS-Addressing ベースのサービスとクライアントを作成するのは非常に簡単です。最初の手順は通常の JAX-WS サービスおよびクライアントの設定を作成することであり、最後の手順は両側でアドレッシングを設定することです。
サービス

以下のエンドポイント実装から始めます。

package org.jboss.test.ws.jaxws.samples.wsa;
        
import javax.jws.WebService;
  @WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
上記のエンドポイントは以下のエンドポイントインターフェースを実装します。
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing"
)
public interface ServiceIface
{
   @WebMethod
   String sayHello();
}
コンパイルされたエンドポイントとインターフェースクラスがディレクトリ /home/username/wsa/cxf/classes にあるとします。次の手順はエンドポイントアーカイブの一部である JAX-WS アーティファクトと WSDL を生成することです。
WSDL および JAX-WS エンドポイントアーティファクトの生成

wsprovide コマンドラインツールを使用して WSDL および JAX-WS アーティファクトを生成します。コマンドは以下のとおりです。

 
cd JBOSS_HOME/bin
./wsprovide.sh --keep --wsdl \
   --classpath=/home/username/wsa/cxf/classes \
   --output=/home/username/wsa/cxf/wsprovide/generated/classes \
   --resource=/home/username/wsa/cxf/wsprovide/generated/wsdl \
   --source=/home/username/wsa/cxf/wsprovide/generated/src \
   org.jboss.test.ws.jaxws.samples.wsa.ServiceImpl
上記のコマンドは以下のアーティファクトを生成します。
コンパイルされたクラス
SayHello.class
SayHelloResponse.class
Java ソース
SayHello.java
SayHelloResponse.java
Contract アーティファクト
AddressingService.wsdl
以前に説明されたすべての生成済みアーティファクトはエンドポイントアーカイブの一部ですが、エンドポイントアーカイブを作成する前に、エンドポイントから生成済み WSDL を参照する必要があります。wsdlLocation アノテーション属性を使用します。これは、war ファイルにパッケージ化される前の更新済みエンドポイント実装です。
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebService;
 
@WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   wsdlLocation = "WEB-INF/wsdl/AddressingService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
作成されたエンドポイント war アーカイブは以下のエントリから構成されます。
     jar -tvf jaxws-samples-wsa.war 
     0 Mon Apr 21 20:39:30 CEST 2008 META-INF/
   106 Mon Apr 21 20:39:28 CEST 2008 META-INF/MANIFEST.MF
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/
   593 Mon Apr 21 20:39:28 CEST 2008 WEB-INF/web.xml
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/classes/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/
   374 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/ServiceIface.class
   954 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/ServiceImpl.class
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/
   703 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/SayHello.class
  1074 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/SayHelloResponse.class
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/wsdl/
  2378 Mon Apr 21 20:39:28 CEST 2008 WEB-INF/wsdl/AddressingService.wsdl
web.xml ファイルの内容は以下のようになります。
  
<?xml version="1.0" encoding="UTF-8"?>

<web-app
   version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
      <servlet-name>AddressingService</servlet-name>
      <servlet-class>org.jboss.test.ws.jaxws.samples.wsa.ServiceImpl</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>AddressingService</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>
通常の JAX-WS クライアントの記述

以下は、Web サービス package.org.jboss.test.ws.jaxws.samples.wsa をルックアップするエンドポイントインターフェースを使用する通常の JAX-WS クライアントです。

package.org.jboss.test.ws.jaxws.samples.wsa:

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public final class SimpleServiceTestCase
{
   private final String serviceURL = "http://localhost:8080/jaxws-samples-wsa/AddressingService";
   
   public static void main(String[] args) throws Exception
   {
      // create service
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsaddressing", "AddressingService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      ServiceIface proxy = (ServiceIface)service.getPort(ServiceIface.class);
      
      // invoke method
      proxy.sayHello();
   }
   
}
エンドポイントおよびクライアント実装が存在しますが、WS-Addressing は存在しません。次の目標は WS-Addressing 機能を有効にすることです。

5.1. WS-Addressing 1.0 の有効化

JbossWS-CXF で WS-Addressing を有効にするには、2 つの手順があります。
  • サービスエンドポイントを @Addressing アノテーションでアノテートします。
  • JAX-WS Web サービス機能を使用して WS-Addressing を設定するようクライアントを変更します。
WS-Addressing を設定するようエンドポイントコードを更新

この時点で、WS-Addressing を設定するためにエンドポイント実装を更新する必要があります。更新されたエンドポイントコードは以下のとおりです。

 
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebService;
import javax.xml.ws.soap.Addressing;
 
@WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   wsdlLocation = "WEB-INF/wsdl/AddressingService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
@Addressing(enabled=true, required=true)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
WS-Addressing を設定するために JAX-WS 2.1 Addressing アノテーションを追加しました。次の手順は、この変更を適用するためにエンドポイントアーカイブを再パッケージ化することです。
WS-Addressing を設定するためにクライアントコードを更新

WS-Addressing を設定するためにクライアント実装を更新する必要があります。更新されたクライアントコードは以下のとおりです。

package org.jboss.test.ws.jaxws.samples.wsa;
 
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.AddressingFeature;
 
public final class AddressingTestCase
{
   private final String serviceURL = "http://localhost:8080/jaxws-samples-wsa/AddressingService";
   
   public static void main(String[] args) throws Exception
   {
      // construct proxy
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsaddressing", "AddressingService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      ServiceIface proxy = (ServiceIface)service.getPort(ServiceIface.class,  new AddressingFeature());
      // invoke method
      proxy.sayHello();
   }
   
}

この時点で、JAX-WS クライアントおよびエンドポイントは WS-Addressing を使用してお互い通信します。