エンドツーエンドのバイナリSOAPアタッチメント(パート3): Webサービスのコーディングおよびテスト

このレッスンでは、Webサービス/セッションBeanクラスにコードを追加し、JPEGファイルのバイト配列への変換と、バイト配列のjava.awt.Imageオブジェクトへの変換を実行します。また、公開されているWebサービス操作にコードを追加し、これらのImageオブジェクトが返されるようにします。最後に、NetBeans IDEの「Webサービスをテスト」ユーティリティを使用して、Webサービスをブラウザでテストします。

Webサービスの完全版サンプルは、NetBeansサンプル・カタログからダウンロードできます。

このチュートリアルのレッスン

このページの内容は、NetBeans IDE 7.2、7.3、7.4および8.0に適用されます
  1. 概要
  2. Webサービスの作成
  3. => Webサービスのコーディングおよびテスト
  4. バイナリ・データを渡すためのスキーマとWSDLファイルの変更
  5. Swingクライアントの作成

このレッスンの目次

  1. Webサービスのコーディング

    1. JPEGファイルをバイト配列として取得
    2. バイト配列をイメージとして読み取る
    3. getFlowerの実装
    4. すべてのJPEGファイルのバイト配列のリストの作成
    5. getThumbnailsの実装
  2. Webサービスのテスト

Webサービスのコーディング

一連のJPEGファイルとWebサービスが含まれるWebアプリケーションを作成しました。このWebサービスは、ステートレス・セッションBeanとして実装されています。このWebサービスには、2つの空のWeb操作が含まれています。このレッスンでは、Webサービスにコードを追加し、JPEGファイルのバイト配列への変換と、バイト配列のjava.awt.Imageオブジェクトへの変換を実行します。また、公開されているWebサービス操作にコードを追加し、これらのImageオブジェクトが返されるようにします。

JPEGファイルをバイト配列として取得

この項では、1組のプライベート・メソッドをFlowerServiceクラス本文に追加します。これらのメソッドは、花の名前を取得し、その花のJPEGファイルへのパスを作成し、JPEGファイルのバイナリ表現(バイト配列)を返します。後の項では、公開されているWebサービス操作にコードを追加して、操作がこれらのプライベート・メソッドをコールするようにします。

  1. プロジェクトの「ソース」ビューを開きます。イメージの名前を取得し、その名前に基づいてイメージへのパスを作成し、そのイメージをバイト配列として取得するコードを追加する必要があります。次のコードをFlowerServiceクラス本文に入力または貼り付けます。
    private byte[] getFlowerBytes(String name) throws IOException {
        URL resource = this.getClass().getResource("/org/flower/resources/"+name+".jpg");
        return getBytes(resource);
    }
  2. IDEがクラスURLを見つけられないことを示す警告が表示されます。java.net.URLのインポート文を、手動で追加するか、[Ctrl]-[Shift]-[I] (Macの場合は[⌘]-[Shift]-[I])を押して追加します。
  3. 新しい警告が表示されます。この警告は、IDEがgetBytesメソッドを見つけられないことを示します。警告アイコンを左クリックし、ヒントをクリックしてgetBytesメソッドを作成します。
    見つからないメソッドを作成するためのヒント
  4. 作成したばかりのgetBytesメソッドがエディタでフォーカスされます。メソッドに次のコードを追加します。このコードは、getFlowerBytesメソッドから渡したURLへの接続を開きInputStreamを返します。次に、1024バイトごとに入力ストリームを読み取り、そのバイトをバイト配列バッファに保存して、バッファからByteArrayOutputStreamに書き込みます。
    private byte[] getBytes(URL resource) throws IOException {
        InputStream in = resource.openStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        for(int read; (read = in.read(buf)) != -1;) {
            bos.write(buf, 0, read);
        }
        return bos.toByteArray();
    }
  5. java.io.InputStreamjava.io.ByteArrayOutputStreamのインポート文を追加します。

バイト配列をイメージとして読み取る

この項では、プライベート・メソッドをFlowerServiceクラス本文に追加します。このメソッドでは、JPEGファイルを表すバイト配列を取得し、java.awt.Imageオブジェクトを返します。バイト配列は、JPEGファイルをバイト配列として取得の項で作成したgetBytes(URL)メソッドによって作成されることに注意してください。

  1. FlowerServiceクラス本文で、getImageという次のプライベート・メソッドを追加します。getImageメソッドの戻り値の型はImageです。このメソッドは、2つのパラメータを取ります。最初のパラメータは、getBytesメソッドによって作成されるバイト配列です。2番目のパラメータは、イメージがサムネイルかどうかを示すブールです。getImageメソッドは、IOExceptionをスローします。
    private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
        }
  2. getImageメソッドの本文で、このメソッドがパラメータとして取得するバイト配列からByteArrayInputStreamを作成する行を追加します。
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
  3. ByteArrayInputStreamからObjectを作成する行を追加します。
    Object source = bis;
  4. 汎用のObjectからImageInputStreamを作成する行を追加します。
    ImageInputStream iis = ImageIO.createImageInputStream(source);
  5. JPEGファイルのデコードが可能な、現在登録されているすべてのImageReaderからIteratorを作成する行を追加します。
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
  6. Iteratorの次の要素からImageReaderを作成する行を追加します。
    ImageReader reader = (ImageReader) readers.next();
  7. デフォルトのイメージ読取りパラメータを作成する行を追加します(ただし、Imageがサムネイルを表す場合はイメージ読取りパラメータに4対1のサブサンプリング処理を追加)。
    ImageReadParam param = reader.getDefaultReadParam();
    if (isThumbnail) {
        param.setSourceSubsampling(4, 4, 0, 0);
    }
  8. 最後に、ImageReaderオブジェクトを使用してImageInputStreamオブジェクトを読み取り、そのオブジェクトに基づくImageとイメージ読取りパラメータを返すコードを追加します。
    reader.setInput(iis, true);
    return reader.read(0, param);
  9. [Ctrl]-[Shift]-[I] (MacOSの場合は[⌘]-[Shift]-[I])を押します。「すべてのインポートを修正」ダイアログが開きます。「すべてのインポートを修正」のデフォルトの修正候補をすべて受け入れ、「OK」をクリックします。
    デフォルトのjava.util.Iteratorクラスが選択された状態を示す「すべてのインポートを修正」ダイアログ

これでgetImageメソッドは完成です。

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
    Object source = bis; // File or InputStream
    ImageInputStream iis = ImageIO.createImageInputStream(source);
    Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
    ImageReader reader = (ImageReader) readers.next();
    ImageReadParam param = reader.getDefaultReadParam();
    if (isThumbnail) {
        param.setSourceSubsampling(4, 4, 0, 0);
    }
    reader.setInput(iis, true);
    return reader.read(0, param);
}

getFlowerの実装

名前によって花を取得してその花のイメージを返すために、次の実装コードをgetFlower()メソッドに追加します。このコードは、getFlowerBytes(name)プライベート・メソッドをコールし、JPEGファイルをバイト配列として取得することに注意してください。次に、getImageプライベート・メソッドをコールし、バイト配列をImageオブジェクトとして返します。

@WebMethod(operationName = "getFlower")
public Image getFlower(@WebParam(name = "name") String name) throws IOException {
    byte[] bytes = getFlowerBytes(name);
    return getImage(bytes, false);
}

すべてのJPEGファイルのバイト配列のリストの作成

  1. FlowerServiceのクラス本文の先頭で、すべての花の名前の文字列配列を作成します。
    private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
  2. ArrayListを作成し、すべての花のバイト配列をListに追加するメソッドを追加します。
    private List allFlowers() throws IOException {
        List flowers = new ArrayList();
        for (String flower:FLOWERS) {
            URL resource = this.getClass().getResource("/org/flower/resources/"+flower+".jpg");
            flowers.add(getBytes(resource));
        }
        return flowers;
    }
  3. java.util.ArrayListjava.util.Listのインポート文を追加します。

getThumbnailsの実装

getThumbnails()メソッドを次のように変更します。ここでは、実装コードを追加し、戻り値の型をListからList<Image>に変更することに注意してください。また、getImageメソッドのisThumbnailのブール値にtrueを渡すことに注意してください。getThumbnails実装コードはallFlowersメソッドをコールし、すべてのJPEGファイルのバイト配列のリストを作成します。次に、getThumbnailsメソッドはImageListを作成し、それぞれの花のgetImageメソッドをコールすることで、その花のバイト配列をImageオブジェクトとして返し、そのImageListに追加します。

@WebMethod(operationName = "getThumbnails")
public List<Image> getThumbnails() throws IOException {
    List<byte[]> flowers = allFlowers();
    List<Image> flowerList = new ArrayList<Image>(flowers.size());
    for (byte[] flower : flowers) {
        flowerList.add(getImage(flower, true));
    }
    return flowerList;
}

これで、Webサービス/セッションを組み合せたBeanは完成しました。このWebサービス・クラスの最終的な形は次のようになります。

package org.flower.service;

import java.awt.Image; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.ejb.Stateless; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream;

@WebService(serviceName = "FlowerService") @Stateless() public class FlowerService {

private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};

@WebMethod(operationName = "getFlower") public Image getFlower(@WebParam(name = "name") String name) throws IOException { byte[] bytes = getFlowerBytes(name); return getImage(bytes, false); }

@WebMethod(operationName = "getThumbnails") public List<Image> getThumbnails() throws IOException { List flowers = allFlowers(); List<Image> flowerList = new ArrayList<Image>(flowers.size()); for (byte[] flower : flowers) { flowerList.add(getImage(flower, true)); } return flowerList; }

private byte[] getFlowerBytes(String name) throws IOException { URL resource = this.getClass().getResource("/org/flower/resources/" + name + ".jpg"); return getBytes(resource); }

private byte[] getBytes(URL resource) throws IOException { InputStream in = resource.openStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; for (int read; (read = in.read(buf)) != -1;) { bos.write(buf, 0, read); } return bos.toByteArray(); }

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); Iterator readers = ImageIO.getImageReadersByFormatName("jpeg"); ImageReader reader = (ImageReader) readers.next(); Object source = bis; // File or InputStream ImageInputStream iis = ImageIO.createImageInputStream(source); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); if (isThumbnail) { param.setSourceSubsampling(4, 4, 0, 0); } return reader.read(0, param); }

private List allFlowers() throws IOException { List flowers = new ArrayList(); for (String flower : FLOWERS) { URL resource = this.getClass().getResource("/flower/album/resources/" + flower + ".jpg"); flowers.add(getBytes(resource)); } return flowers; } }

Webサービスのテスト

Webサービスが完成したので、デプロイとテストを実行できます。

Webサービスをテストするには:

  1. 「FlowerAlbumService」ノードを右クリックし、「デプロイ」を選択します。IDEはソース・コードをコンパイルし、GlassFishサーバーを起動して、プロジェクトのWARファイルをサーバーにデプロイします。「サービス」ウィンドウを開くと、デプロイされたFlowerServiceがサーバーの「アプリケーション」ノードに表示されます。

    重要: GlassFish Server Open Source Editionはバージョン3.1以降である必要があります。

    「サービス」ウィンドウ内のデプロイ済FlowerService
  2. プロジェクトの「Webサービス」ノードを展開します。「FlowerService」を右クリックし、「Webサービスをテスト」を選択します。
    「Webサービスをテスト」オプションを表示するコンテキスト・メニュー
  3. Webサービスのテスト・ページがブラウザで開きます。「getFlower」パラメータ・フィールドに「rose」と入力します。
    Webサービスのテスト・ページが開きます
  4. getFlower」ボタンを押します。IDEが、この呼出しに関する情報をブラウザに表示します。「Method Returned」を見ると、中身が文字化けしていることがわかります。見たいのは記号の羅列ではなく、イメージです。しかし、java.awt.Imageは有効なスキーマ・タイプではないため、バイナリのimage/jpegデータを返すようにスキーマ・ファイルを手動で構成する必要があります。これは、次のチュートリアルで行います。
    ブラウザ・ウィンドウに表示されたWebサービスのテスト・ページの結果
  5. 次の手順:

    バイナリ・データを渡すためのスキーマとWSDLファイルの変更


    メーリング・リストに登録することによって、NetBeans IDE Java EE開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo