blob: d082bd55ad378621ef2a9cdf53590c5e83792d0b [file] [log] [blame]
//
// 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クライアントの作成+]
6. <<coding-ws,Webサービスのコーディング>>
7. <<retrieve-jpeg-as-bytes,JPEGファイルをバイト配列として取得>>
8. <<read-bytes-as-image,バイト配列をイメージとして読み取る>>
9. <<implement-getflower,getFlowerの実装>>
10. <<create-byte-array-list,すべてのJPEGファイルのバイト配列のリストの作成>>
11. <<implement-getthumbnails,getThumbnailsの実装>>
[start=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);
}
----
[start=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])を押して追加します。
[start=3]
. 新しい警告が表示されます。この警告は、IDE ``getBytes`` メソッドを見つけられないことを示します。警告アイコンを左クリックし、ヒントをクリックして ``getBytes`` メソッドを作成します。
image::images/create-method-tip.png[]
[start=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();
}
----
[start=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 {
}
----
[start=2]
. ``getImage`` メソッドの本文で、このメソッドがパラメータとして取得するバイト配列から ``link:http://download.oracle.com/javase/6/docs/api/java/io/ByteArrayInputStream.html[+ByteArrayInputStream+]`` を作成する行を追加します。
[source,java]
----
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
----
[start=3]
. ``ByteArrayInputStream`` から ``Object`` を作成する行を追加します。
[source,java]
----
Object source = bis;
----
[start=4]
. 汎用の ``Object`` から ``link:http://download.oracle.com/javase/6/docs/api/javax/imageio/stream/ImageInputStream.html[+ImageInputStream+]`` を作成する行を追加します。
[source,java]
----
ImageInputStream iis = ImageIO.createImageInputStream(source);
----
[start=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");
----
[start=6]
. ``Iterator`` の次の要素から ``ImageReader`` を作成する行を追加します。
[source,java]
----
ImageReader reader = (ImageReader) readers.next();
----
[start=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);
}
----
[start=8]
. 最後に、 ``ImageReader`` オブジェクトを使用して ``ImageInputStream`` オブジェクトを読み取り、そのオブジェクトに基づく ``Image`` とイメージ読取りパラメータを返すコードを追加します。
[source,java]
----
reader.setInput(iis, true);
return reader.read(0, param);
----
[start=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"};
----
[start=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;
}
----
[start=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[]
[start=2]
. プロジェクトの「Webサービス」ノードを展開します。「FlowerService」を右クリックし、「Webサービスをテスト」を選択します。
image::images/test-ws-node.png[]
[start=3]
. Webサービスのテスト・ページがブラウザで開きます。「 ``getFlower`` 」パラメータ・フィールドに「rose」と入力します。
image::images/ws-tester.png[]
[start=4]
. ``getFlower`` 」ボタンを押します。IDEが、この呼出しに関する情報をブラウザに表示します。「Method Returned」を見ると、中身が文字化けしていることがわかります。見たいのは記号の羅列ではなく、イメージです。しかし、 ``java.awt.Image`` は有効なスキーマ・タイプではないため、バイナリのimage/jpegデータを返すようにスキーマ・ファイルを手動で構成する必要があります。これは、次のチュートリアルで行います。
image::images/ws-tester-badschema.png[]
[start=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開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。