// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= エンドツーエンドのバイナリSOAPアタッチメント(パート3): Webサービスのコーディングおよびテスト
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: エンドツーエンドのバイナリSOAPアタッチメント(パート3): Webサービスのコーディングおよびテスト - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, エンドツーエンドのバイナリSOAPアタッチメント(パート3): Webサービスのコーディングおよびテスト

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

Webサービスの完全版サンプルは、link:https://netbeans.org/projects/samples/downloads/download/Samples%252FWeb%2520Services%252FWeb%2520Service%2520Passing%2520Binary%2520Data%2520--%2520EE6%252FFlowerAlbumService.zip[+NetBeansサンプル・カタログ+]からダウンロードできます。

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

image::images/netbeans-stamp-80-74-73.png[title="このページの内容は、NetBeans IDE 7.2、7.3、7.4および8.0に適用されます"]

1. link:./flower_overview.html[+概要+]
2. link:flower_ws.html[+Webサービスの作成+]
3. => Webサービスのコーディングおよびテスト
4. link:./flower_wsdl_schema.html[+バイナリ・データを渡すためのスキーマとWSDLファイルの変更+]
5. link:./flower_swing.html[+Swingクライアントの作成+]


1. <<coding-ws,Webサービスのコーディング>>

1. <<retrieve-jpeg-as-bytes,JPEGファイルをバイト配列として取得>>
2. <<read-bytes-as-image,バイト配列をイメージとして読み取る>>
3. <<implement-getflower,getFlowerの実装>>
4. <<create-byte-array-list,すべてのJPEGファイルのバイト配列のリストの作成>>
5. <<implement-getthumbnails,getThumbnailsの実装>>
2. <<test-ws,Webサービスのテスト>>


[[coding-ws]]
== Webサービスのコーディング

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


[[retrieve-jpeg-as-bytes]]
=== JPEGファイルをバイト配列として取得

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

1. プロジェクトの「ソース」ビューを開きます。イメージの名前を取得し、その名前に基づいてイメージへのパスを作成し、そのイメージをバイト配列として取得するコードを追加する必要があります。次のコードを ``FlowerService`` クラス本文に入力または貼り付けます。

[source,java]
----

private byte[] getFlowerBytes(String name) throws IOException {
    URL resource = this.getClass().getResource("/org/flower/resources/"+name+".jpg");
    return getBytes(resource);
}
----
2. IDEがクラス ``URL`` を見つけられないことを示す警告が表示されます。 ``link:http://download.oracle.com/javase/6/docs/api/java/net/URL.html[+java.net.URL+]`` のインポート文を、手動で追加するか、[Ctrl]-[Shift]-[I] (Macの場合は[⌘]-[Shift]-[I])を押して追加します。
3. 新しい警告が表示されます。この警告は、IDEが ``getBytes`` メソッドを見つけられないことを示します。警告アイコンを左クリックし、ヒントをクリックして ``getBytes`` メソッドを作成します。
image::images/create-method-tip.png[]
4. 作成したばかりの ``getBytes`` メソッドがエディタでフォーカスされます。メソッドに次のコードを追加します。このコードは、 ``getFlowerBytes`` メソッドから渡したlink:http://download.oracle.com/javase/6/docs/api/java/net/URL.html#openStream%28%29[+URLへの接続を開き+]、 ``link:http://download.oracle.com/javase/6/docs/api/java/io/InputStream.html[+InputStream+]`` を返します。次に、1024バイトごとに入力ストリームを読み取り、そのバイトをバイト配列バッファに保存して、バッファから ``link:http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayOutputStream.html[+ByteArrayOutputStream+]`` に書き込みます。

[source,java]
----

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.InputStream`` と ``java.io.ByteArrayOutputStream`` のインポート文を追加します。


[[read-bytes-as-image]]
=== バイト配列をイメージとして読み取る

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

1.  ``FlowerService`` クラス本文で、 ``getImage`` という次のプライベート・メソッドを追加します。 ``getImage`` メソッドの戻り値の型は ``Image`` です。このメソッドは、2つのパラメータを取ります。最初のパラメータは、 ``getBytes`` メソッドによって作成されるバイト配列です。2番目のパラメータは、イメージがサムネイルかどうかを示すブールです。 ``getImage`` メソッドは、 ``IOException`` をスローします。

[source,java]
----

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
    }
----
2.  ``getImage`` メソッドの本文で、このメソッドがパラメータとして取得するバイト配列から ``link:http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayInputStream.html[+ByteArrayInputStream+]`` を作成する行を追加します。

[source,java]
----

ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
----
3.  ``ByteArrayInputStream`` から ``Object`` を作成する行を追加します。

[source,java]
----

Object source = bis;
----
4. 汎用の ``Object`` から ``link:http://download.oracle.com/javase/6/docs/api/javax/imageio/stream/ImageInputStream.html[+ImageInputStream+]`` を作成する行を追加します。

[source,java]
----

ImageInputStream iis = ImageIO.createImageInputStream(source);
----
5. JPEGファイルのデコードが可能な、現在登録されているすべての ``link:http://download.oracle.com/javase/6/docs/api/javax/imageio/ImageReader.html[+ImageReader+]`` から ``link:http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html[+Iterator+]`` を作成する行を追加します。

[source,java]
----

Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
----
6.  ``Iterator`` の次の要素から ``ImageReader`` を作成する行を追加します。

[source,java]
----

ImageReader reader = (ImageReader) readers.next();
----
7. デフォルトのlink:http://download.oracle.com/javase/6/docs/api/javax/imageio/IIOParam.html[+イメージ読取りパラメータ+]を作成する行を追加します(ただし、 ``Image`` がサムネイルを表す場合はイメージ読取りパラメータに4対1のlink:http://download.oracle.com/javase/6/docs/api/javax/imageio/IIOParam.html#setSourceSubsampling%28int,%20int,%20int,%20int%29[+サブサンプリング処理+]を追加)。

[source,java]
----

ImageReadParam param = reader.getDefaultReadParam();
if (isThumbnail) {
    param.setSourceSubsampling(4, 4, 0, 0);
}
----
8. 最後に、 ``ImageReader`` オブジェクトを使用して ``ImageInputStream`` オブジェクトを読み取り、そのオブジェクトに基づく ``Image`` とイメージ読取りパラメータを返すコードを追加します。

[source,java]
----

reader.setInput(iis, true);
return reader.read(0, param);
----
9. [Ctrl]-[Shift]-[I] (MacOSの場合は[⌘]-[Shift]-[I])を押します。「すべてのインポートを修正」ダイアログが開きます。「すべてのインポートを修正」のデフォルトの修正候補をすべて受け入れ、「OK」をクリックします。
image::images/fix-getimage-imports.png[]

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


[source,java]
----

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);
}
----


[[implement-getflower]]
=== getFlowerの実装

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


[source,java]
----

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


[[create-byte-array-list]]
=== すべてのJPEGファイルのバイト配列のリストの作成

1.  ``FlowerService`` のクラス本文の先頭で、すべての花の名前の文字列配列を作成します。

[source,java]
----

private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
----
2.  ``link:http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html[+ArrayList+]`` を作成し、すべての花のバイト配列を ``List`` に追加するメソッドを追加します。

[source,java]
----

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.ArrayList`` と ``java.util.List`` のインポート文を追加します。


[[implement-getthumbnails]]
=== getThumbnailsの実装

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


[source,java]
----

@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サービス・クラスの最終的な形は次のようになります。


[source,java]
----

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;
    }
}
----


[[test-ws]]
== Webサービスのテスト

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

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

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

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

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

== 次の手順:

link:./flower_wsdl_schema.html[+バイナリ・データを渡すためのスキーマとWSDLファイルの変更+]

link:/about/contact_form.html?to=3&subject=Feedback:%20Flower%20Coding%20WS%20EE6[+このチュートリアルに関するご意見をお寄せください+]

link:../../../community/lists/top.html[+nbj2ee@netbeans.orgメーリング・リスト+]に登録することによって、NetBeans IDE Java EE開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。

