| 
      
 
この節では、RESTful な Web サービスをプログラミングする方法について説明します。
 
REST (Representational State Transfer) とは、SOAP のように追加のメッセージ層を使用することなく、HTTP などの標準化されたインタフェースでデータを転送するためのシンプルなインタフェースを記述したものです。REST は、ユニークな URI で特定できるステートレス サービスを「リソース」(特定の情報のソース) とみなし、これらを作成するための設計ルールを提供します。クライアントがリソースにアクセスする際は、この URI と返されたリソースの「表現」を使用します。クライアントは、新しいリソース表現を受け取るたびに「転送」状態に設定されます。
 
RESTful なエンドポイントを構築するには、javax.xml.ws.Provider<T> インタフェースの invoke() メソッドを使用します。Provider インタフェースは、サービス エンドポイント インタフェース (SEI) を構築するための動的な代替手段を提供します。
 
この節では、RESTful な Web サービスを実装するために必要な JWS ファイルをプログラミングおよびコンパイルする方法について説明します。この手順では、これらの JWS ファイルをゼロから作成する方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用してください。
 
Ant ベースの開発環境を設定済みであり、かつ jwsc Ant タスクを実行して、Web サービスをデプロイするためのターゲットを追加できる、作業用の build.xml ファイルがあることが前提となっています。詳細については、『JAX-WS を使用した WebLogic Web サービスの開始』を参照してください。
| 
 | 
||
prompt> ant build-rest  | 
||
 
次のサンプルでは、RESTful な 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();
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);
    }
  }
    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>";
        }
    }
} 
RESTful な Web サービスを実装する JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのサンプル コードは、上述のサンプルでは太字で示されています。
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.MessageContext のQUERY_STRING フィールドを使用してリクエスト文字列を取得する。その後、クエリ文字列が createSource() メソッドに渡され、指定した値に最も近い市、州、緯度、経度が返されます。String query =
(String)messageContext.get(MessageContext.QUERY_STRING);
.
.
.
return createSource(query);
 
Web サービス クライアントから RESTful な Web サービスにアクセスするには、リソースの URI を使用します。次に例を示します。
http://localhost:7001/NearbyCity/NearbyCityService?lat=35&long=-120 
この例では、緯度 (lat) と経度 (long) の値を指定して、必要なリソースにアクセスしています。
    
         |