HomeDocumentation > 9. サンプル・アプリケーション > 9.c. JAX-WS を利用した簡単な Web サービス

アプリケーションの概略

この文章で述べられているサンプル・アプリケーションは2つの整数の足し算を行う単純な計算機です。クライアント・アプリケーションは J2EE アプリケーションではありません。Web サービスをアプリケーションの機能として呼び出す通常の Java アプリケーションです。Web サービスは Geronimo アプリケーション・サーバー上にサーブレットとして公開されています。

サービスの実装

Calculator インターフェースは Web サービスのサービス・エンドポイント・インターフェース (SEI) を定義しています。

Calculator.java
package org.apache.geronimo.samples.jws;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

@WebService(name="CalculatorPortType",
            targetNamespace = "http://jws.samples.geronimo.apache.org")
public interface Calculator {

    @WebMethod
    public int add(@WebParam(name = "value1") int value1,
                   @WebParam(name = "value2") int value2);

}

CalculatorService クラスは Web サービスのビジネス・ロジックを実装しています。 SEI にあるすべてのメソッドを実装しています。このクラスでは Calculator インターフェースを実装する必要はありませんが、このインターフェースは @WebService.endpointInterface アノテーションを通じて参照されます。このクラスは javax.servlet.Servlet クラスを継承していませんが、web.xml ファイルを通じてサーブレットとして公開されます。
@Resource アノテーションが付けられた context 変数へ実行時に注入されます。WebServiceContext はメッセージ・コンテキストとセキュリティー情報を保持するために利用されます。

CalculatorService.java
package org.apache.geronimo.samples.jws;

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;

@WebService(serviceName = "Calculator",
            portName="CalculatorPort",
            endpointInterface = "org.apache.geronimo.samples.jws.Calculator",
            targetNamespace = "http://jws.samples.geronimo.apache.org",
            wsdlLocation = "WEB-INF/wsdl/CalculatorService.wsdl")
public class CalculatorService implements Calculator {

    @Resource
    private WebServiceContext context;

    public int add(int value1, int value2) {
        System.out.println("User Principal: " + context.getUserPrincipal());
        return value1 + value2;
    }
}

web.xml は Web サービスのデプロイに利用されます。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
	<servlet>
		<display-name>CalculatorService</display-name>
		<servlet-name>CalculatorService</servlet-name>
		<servlet-class>
			org.apache.geronimo.samples.jws.CalculatorService
		</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>CalculatorService</servlet-name>
		<url-pattern>/calculator</url-pattern>
	</servlet-mapping>

        .....
</web-app>

web.xml

web.xml は、簡単な JAX-WS Web サービスのデプロイには必要ありません。web.xml が与えられない場合、デプロイ時に自動的に生成されます。

geronimo-web.xml ファイルは任意ですが、このサンプルではモジュール名を記述しています。このプロジェクトの情報(例えばモジュールの一意名や依存関係など)は、<environment> タグ内に記述されています。今回は依存関係がありませんので列挙されていません。しかし、このモジュールに一連の一意名を付けておくほうがよいです。そうすれば、後々他のアプリケーションから参照することができます。

geronimo-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
  <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
    <dep:moduleId>
      <dep:groupId>${pom.groupId}</dep:groupId>
      <dep:artifactId>${pom.artifactId}</dep:artifactId>
      <dep:version>${version}</dep:version>
      <dep:type>war</dep:type>
    </dep:moduleId>
  </dep:environment>

 <context-root>/jaxws-calculator</context-root>

 <service-ref>
   <service-ref-name>services/Calculator</service-ref-name>
   <port>
      <port-name>CalculatorPort</port-name>
      <protocol>http</protocol>
      <host>localhost</host>
      <port>8080</port>
      <uri>/jaxws-calculator/calculator</uri>
   </port>
 </service-ref>
</web-app>

以下のように、WSDL ファイルは Web サービスを記述します。

CalculatorService.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="Calculator"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://jws.samples.geronimo.apache.org"
    xmlns:tns="http://jws.samples.geronimo.apache.org">

    <wsdl:types>
        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    xmlns="http://jws.samples.geronimo.apache.org"
                    targetNamespace="http://jws.samples.geronimo.apache.org"
                    attributeFormDefault="unqualified" elementFormDefault="qualified">

             <xsd:element name="add">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element name="value1" type="xsd:int"/>
                      <xsd:element name="value2" type="xsd:int"/>
                   </xsd:sequence>
                </xsd:complexType>
             </xsd:element>

             <xsd:element name="addResponse">
                <xsd:complexType>
                   <xsd:sequence>
                      <xsd:element name="return" type="xsd:int"/>
                   </xsd:sequence>
                </xsd:complexType>
             </xsd:element>
        </xsd:schema>
    </wsdl:types>

    <wsdl:message name="add">
       <wsdl:part name="add" element="tns:add"/>
    </wsdl:message>

    <wsdl:message name="addResponse">
       <wsdl:part name="addResponse" element="tns:addResponse"/>
    </wsdl:message>

    <wsdl:portType name="CalculatorPortType">
       <wsdl:operation name="add">
         <wsdl:input name="add" message="tns:add"/>
         <wsdl:output name="addResponse" message="tns:addResponse"/>
       </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="CalculatorSoapBinding" type="tns:CalculatorPortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

        <wsdl:operation name="add">
            <soap:operation soapAction="add" style="document"/>
            <wsdl:input name="add">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="addResponse">
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>

    </wsdl:binding>

    <wsdl:service name="Calculator">
        <wsdl:port name="CalculatorPort" binding="tns:CalculatorSoapBinding">
            <soap:address location="http://localhost:8080/jaxws-calculator-1.0/calculator"/>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>

webservices.xml

J2EE バージョン 1.4 では、Web サービスの定義のために webservices.xml ファイルも必要です。Java EE 5 では、このファイルは任意です。今回の例では必要としていません。

JSP ベースの JAX-WS クライアント

add.jspCalculatorService Web サービスを利用する基本的なクライアントです。

add.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ page import="javax.naming.InitialContext,javax.xml.ws.Service,org.apache.geronimo.samples.jws.Calculator"%>
<html  xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <title>Apache Geronimo Sample Application - JAX-WS Calculator</title>
  <meta content="text/html; CHARSET=iso-8859-1" http-equiv="Content-Type">
</head>

<BODY>
  <font face="Verdana, Helvetica, Arial">

    <h3>This is a JAX-WS web service sample application.   Please type the value 1 and value 2 below to see the add result.</h3>
    <form action="add.jsp">
        Value 1: <input type="text" name="value1">   Value 2: <input type="text" name="value2"> <input type="submit" value="Add">
    </form>
    <br>
<%
    String value1 = request.getParameter( "value1" );
    String value2 = request.getParameter( "value2" );

    if (value1 != null && value1.trim().length() > 0 &&
        value2 != null && value2.trim().length() > 0) {

        out.println("<h4>");

        try {
            int v1 = Integer.parseInt(value1);
            int v2 = Integer.parseInt(value2);

            InitialContext ctx = new InitialContext();
            Service service = (Service)ctx.lookup("java:comp/env/services/Calculator");
            Calculator calc = service.getPort(Calculator.class);
            int sum = calc.add(v1, v2);
            out.println("Result: " + v1 + " + " + v2 + " = " + sum);
        } catch ( Exception e ) {
            out.println("Error: " + e.getMessage());
       }

       out.println("</h4>");
    }
%>

  </FONT>
</body>
</html>

add.jsp は JNDI から Web サービスへの参照を探します。Web サービスへの参照は web.xml ファイルに追加されます。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
        .....

        <service-ref>
            <service-ref-name>services/Calculator</service-ref-name>
            <service-interface>javax.xml.ws.Service</service-interface>
            <wsdl-file>WEB-INF/wsdl/CalculatorService.wsdl</wsdl-file>
        </service-ref>

        .....
</web-app>

Resource injection in JSP

JSP ではリソースの注入をサポートしていないので、service-ref は明確に web.xml へ追加しなければいけません。

サンプル・アプリケーションのビルドとデプロイ

SVN からサンプルのソースコードをチェックアウトすることができます。

svn checkout http://svn.apache.org/repos/asf/geronimo/samples/trunk/samples/jaxws-calculator calculator

ソースコードは calculator/ ディレクトリーにチェックアウトされます。このサンプルコードは calculator/jaxws-calculator-war/ の中に入っています。

必要なツール

Calculator サンプル・アプリケーションのデプロイとビルドに必要なツールは以下のとおりです。

Apache Maven 2.0.x

Apache Maven は Calculator アプリケーションのビルドに利用されます。

ビルド

ソースコードのコンパイル

コマンド・プロンプトで、calculator/jaxws-calculator-war/ フォルダーに移動し以下のコマンドを実行してください。

mvn install

コンパイルが成功すると、jaxws-calculator-war-2.0-SNAPSHOT.war ファイルが target/ サブ・フォルダーに作られます。

デプロイ

axws-calculator-war-2.0-SNAPSHOT.war を Geronimo コンソール (http://localhost:8080/console) を利用してデプロイします。

  1. Console Navigation パネルから Deploy New を選択してください。
  2. Archive 入力欄に calculator/jaxws-calculator-war/target/ フォルダーの jaxws-calculator-war-2.0-SNAPSHOT.war を読み込んでください。
  3. Install ボタンを押してアプリケーションをサーバへデプロイしてください。

サンプルのテスト

テストすると、このサンプルのサービスは add.jsp (http://localhost:8080/jaxws-calculator/add.jsp) を使って Web サービスを呼び出します。JSP が読み込まれたら、2つの値を入力し、Add ボタンを押してください。足し算の結果が下に表示されます。例えば、以下のとおりです。