プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの開発
12c (12.2.1)
E69970-01
  目次へ移動
目次

前
 
次
 

30 XML over HTTPを使用するWebサービスのプログラミング

この章では、XML over HTTPを使用するWebサービスのプログラミング方法について説明します。

この章の内容は次のとおりです:

XML over HTTPを使用するWebサービスのプログラミングの概要

標準的なSOAP over HTTPの使用例に加えて、XML over HTTP方式の一部のWebサービスでもWebLogic JAX-WSを使用できます。XML over HTTP方式を使用すると、JAX-WSプログラミング・モデルの利便性を活用しながら、単純でRESTfulなWebサービスを構築できます。


注意:

ベスト・プラクティスとしてお薦めする方法は、Jersey JAX-RS RIを使用してRESTfulなWebサービスを開発することです(『Oracle WebLogic Server RESTful Webサービスの開発と保護』を参照)。Jersey JAX-RS RIでは、RESTfulなWebサービスを構築するために本番環境として使用できるオープン・ソースのRIが提供され、すべてのHTTPメソッドがサポートされます。

HTTPプロトコルを使用してWebサービス・リソースにアクセスする場合、リソース識別子はリソースのURLであり、このリソースで実行される標準の操作はHTTPの1つのメソッド(GET、PUT、DELETE、POST、またはHEAD)です。


注意:

このJAX-WS実行で、サポートされたHTTPメソッドのセットがGETおよびPOSTに限定されています。DELETE、PUTおよびHEADがサポートされません。これらのメソッドを含むどのHTTPリクエストも405不可のメソッドというエラー・メッセージが表示され、拒否されます。

PUTおよびDELETEの機能が必須の場合、POSTメソッドで実行される実際のメソッドをトンネリングすることによって目的のアクションを実行できます。これは、オーバーロードPOSTと呼ばれる回避策です。(「REST過負荷POST」でのWeb検索は、これを実行するためのいくつかの方法を返します。)


javax.xml.ws.Provider<T>インタフェースのinvoke()メソッドを使用してRESTfulに類似したエンドポイントを構築します(http://docs.oracle.com/javaee/7/api/javax/xml/ws/Provider.htmlを参照)。Providerインタフェースは、サービス・エンドポイント・インタフェース(SEI)を構築するための動的な代替手段を提供します。

この項の手順では、XML over HTTPを使用してWebサービスを実装するために必要なJWSファイルをプログラミングおよびコンパイルする方法について説明します。この手順では、これらのJWSファイルをゼロから作成する方法を示しています。既存のJWSファイルを更新する場合は、この手順をガイドとして利用してください。

Antベースの開発環境を設定済であり、かつjwsc Antタスクを実行してWebサービスをデプロイするためのターゲットを追加できる、作業用のbuild.xmlファイルがあることが前提となっています。詳細は、第3章「JAX-WS Webサービスの開発」を参照してください。

表30-1 RESTfulなWebサービスのプログラミング手順

#
手順 説明

1

XML over HTTPを使用するWebサービスを実装する、新しいJWSファイルを作成するか、既存のJWSファイルを更新します。

使い慣れたIDEまたはテキスト・エディタを使用します。「XML over HTTPを使用するWebサービスのプログラミングのガイドライン」を参照してください。

2

build.xmlファイルを更新して、JWSファイルをWebサービスにコンパイルするjwsc Antタスクの呼出しを含めます。

例:

   <jwsc srcdir="." destdir="output/restEar">
      <jws file="NearbyCity.java" type="JAXWS"/>
    </jwsc>

詳細は、「jwsc WebLogic WebサービスAntタスクの実行」を参照してください。

3

Antターゲットを実行して、Webサービスを構築します。

例:

prompt> ant build-rest

4

Webサービスを通常どおりデプロイします。

「WebLogic Webサービスのデプロイとアンデプロイ」を参照してください。

5

Webサービス・クライアントからWebサービスにアクセスします。

「クライアントからWebサービスにアクセスする」を参照してください。


XML over HTTPを使用するWebサービスのプログラミングのガイドライン

次のサンプルでは、XML over HTTPを使用するWebサービスを実装する簡単なJWSファイルを示します。太字で示されたJavaコードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。

package examples.webservices.jaxws.rest;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider; 
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.http.HTTPException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.StringTokenizer;

@WebServiceProvider(
   targetNamespace="http://example.org",
   serviceName = "NearbyCityService")
@BindingType(value = HTTPBinding.HTTP_BINDING) 

public class NearbyCity implements Provider<Source> { 
  @Resource(type=Object.class)
  protected WebServiceContext wsContext;

  public Source invoke(Source source)  { 
    try {
        MessageContext messageContext = wsContext.getMessageContext();

        // Obtain the HTTP mehtod of the input request.
        javax.servlet.http.HttpServletRequest servletRequest = 
          (javax.servlet.http.HttpServletRequest)messageContext.get(
           MessageContext.SERVLET_REQUEST);
        String httpMethod = servletRequest.getMethod();
        if (httpMethod.equalsIgnoreCase("GET"));
        {

            String query =
                 (String)messageContext.get(MessageContext.QUERY_STRING); 
            if (query != null && query.contains("lat=") &&
                query.contains("long=")) {
                return createSource(query); 
            } else {
                System.err.println("Query String = "+query);
                throw new HTTPException(404);
            }
            } catch(Exception e) {
              e.printStackTrace();
              throw new HTTPException(500);
            }
        }
        } else {
   // This operation only supports "GET"
       throw new HTTPException405);
   }
    private Source createSource(String str) throws Exception {
        StringTokenizer st = new StringTokenizer(str, "=&/");
        String latLong = st.nextToken();
        double latitude = Double.parseDouble(st.nextToken());
        latLong = st.nextToken();
        double longitude = Double.parseDouble(st.nextToken());
        City nearby = City.findNearBy(latitude, longitude);
        String body = nearby.toXML();
        return new StreamSource(new ByteArrayInputStream(body.getBytes()));
    }

    static class City {
         String city;
         String state;
         double latitude;
         double longitude;
         City(String city, double lati, double longi, String st) {
             this.city = city;
             this.state = st;
             this.latitude = lati;
             this.longitude = longi;
         }

         double distance(double lati, double longi) {
            return Math.sqrt((lati-this.latitude)*(lati-this.latitude) + 
                (longi-this.longitude)*(longi-this.longitude)) ;
         }

         static final City[] cities = {
            new City("San Francisco",37.7749295,-122.4194155,"CA"),
            new City("Columbus",39.9611755,-82.9987942,"OH"),
            new City("Indianapolis",39.7683765,-86.1580423,"IN"),
            new City("Jacksonville",30.3321838,-81.655651,"FL"),
            new City("San Jose",37.3393857,-121.8949555,"CA"),
            new City("Detroit",42.331427,-83.0457538,"MI"),
            new City("Dallas",32.7830556,-96.8066667,"TX"),
            new City("San Diego",32.7153292,-117.1572551,"CA"),
            new City("San Antonio",29.4241219,-98.4936282,"TX"),
            new City("Phoenix",33.4483771,-112.0740373,"AZ"),
            new City("Philadelphia",39.952335,-75.163789,"PA"),
            new City("Houston",29.7632836,-95.3632715,"TX"),
            new City("Chicago",41.850033,-87.6500523,"IL"),
            new City("Los Angeles",34.0522342,-118.2436849,"CA"),
            new City("New York",40.7142691,-74.0059729,"NY")};
        static City findNearBy(double lati, double longi) {
            int n = 0;
            for (int i = 1; i < cities.length; i++)  {
                if (cities[i].distance(lati, longi) <  
                     cities[n].distance(lati, longi)) {
                    n = i;
                }
            }
            return cities[n];
        }

        public String toXML() {
             return "<ns:NearbyCity xmlns:ns=\"http://example.org\"><City>"
                  +this.city+"</City><State>"+ this.state+"</State><Lat>"
                  +this.latitude +
                  "</Lat><Lng>"+this.longitude+"</Lng></ns:NearbyCity>";
        }
    }
}

XML over HTTPを使用するWebサービスを実装するJWSファイルをプログラミングする際には、次のガイドラインに従います。ガイドラインのコード・スニペットは、前述のサンプルでは太字で示されています。

  • プロバイダWebサービスを実装するために必要なパッケージをインポートします。

    import javax.xml.ws.WebServiceProvider;
    import javax.xml.ws.BindingType;
    import javax.xml.ws.Provider;
    
  • Provider実装クラスにアノテーションを追加し、HTTPに対するバインディング・タイプを設定します。

    @WebServiceProvider(
       targetNamespace="http://example.org",
       serviceName = "NearbyCityService")
    @BindingType(value = HTTPBinding.HTTP_BINDING)
    
  • Providerインタフェースのinvoke()メソッドを実装します。

    public class NearbyCity implements Provider<Source> {
      @Resource(type=Object.class)
      protected WebServiceContext wsContext;
    
      public Source invoke(Source source)  {
      ...
      }
    
  • 処理するために、javax.xml.ws.handler.MessageContextQUERY_STRINGフィールドを使用してリクエスト文字列を取得します(メッセージURL http://docs.oracle.com/javaee/7/api/javax/xml/ws/handler/MessageContext.htmlを参照)。その後、問合せ文字列がcreateSource()メソッドに渡され、指定した値に最も近い市、州、緯度、経度が返されます。

    String query =
                 (String)messageContext.get(MessageContext.QUERY_STRING); 
    .
    .
    .
    return createSource(query);
    

クライアントからWebサービスにアクセスする

Webサービス・クライアントからWebサービスにアクセスするには、リソースのURIを使用します。例:

URL url = new URL (http://localhost:7001/NearbyCity/NearbyCityService?lat=35&long=-120);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
// Get result
InputStream is = connection.getInputStream();

この例では、緯度(lat)と経度(long)の値を指定して、必要なリソースにアクセスしています。

XML over HTTPを使用するWebサービスの保護

Webアプリケーションの保護に使用するメソッドと同じメソッドを使用して、XML over HTTPを使用するWebサービスを保護することができます。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のWebアプリケーションおよびEJBリソースの保護のオプションに関する項を参照してください。