エンドツーエンドのバイナリ SOAP アタッチメント (パート 3): Web サービスのコーディングおよびテスト
このレッスンでは、Web サービス/セッション Bean クラスにコードを追加し、JPEG ファイルのバイト配列への変換と、バイト配列の java.awt.Image オブジェクトへの変換を実行します。また、公開されている Web サービスオペレーションにコードを追加し、これらの Image オブジェクトが返されるようにします。最後に、NetBeans IDE の「Web サービスをテスト」ユーティリティーを使用して、Web サービスをブラウザでテストします。
Web サービスの完全版サンプルは、「NetBeans サンプルカタログ 」からダウンロードできます。
このチュートリアルのレッスン
概要
Web サービスの作成
=> Web サービスのコーディングおよびテスト
バイナリデータを渡すためのスキーマと WSDL ファイルの変更
Swing クライアントの作成
このレッスンの目次
Web サービスのコーディング
JPEG ファイルをバイト配列として取得
バイト配列を画像として読み取る
getFlower の実装
すべての JPEG ファイルのバイト配列のリストの作成
getThumbnails の実装
Web サービスのテスト
Web サービスのコーディング
一連の JPEG ファイルと Web サービスが含まれる Web アプリケーションを作成しました。この Web サービスは、ステートレスセッション Bean として実装されています。この Web サービスには、2 つの空の Web オペレーションが含まれています。このレッスンでは、Web サービスにコードを追加し、JPEG ファイルのバイト配列への変換と、バイト配列の java.awt.Image オブジェクトへの変換を実行します。また、公開されている Web サービスオペレーションにコードを追加し、これらの Image オブジェクトが返されるようにします。
JPEG ファイルをバイト配列として取得
この節では、1 組の非公開メソッドを FlowerService クラス本文に追加します。これらのメソッドは、花の名前を取得し、その花の JPEG ファイルへのパスを作成し、JPEG ファイルのバイナリ表現 (バイト配列) を返します。あとの節では、公開されている Web サービスオペレーションにコードを追加して、オペレーションがこれらの非公開メソッドを呼び出すようにします。
プロジェクトの「ソース」ビューを開きます。画像の名前を取得し、その名前に基づいて画像へのパスを作成し、その画像をバイト配列として取得するコードを追加する必要があります。次のコードを FlowerService クラス本文に入力またはペーストします。
private byte[] getFlowerBytes(String name) throws IOException {
URL resource = this.getClass().getResource("/org/flower/resources/"+name+".jpg");
return getBytes(resource);
}
IDE がクラス URL を見つけられないことを示す警告が表示されます。java.net.URL のインポート文を、手動で追加するか、Ctrl-Shift-I (Mac の場合は ⌘-Shift-I) を押して追加します。
新しい警告が表示されます。この警告は、IDE が getBytes メソッドを見つけられないことを示します。警告アイコンを左クリックし、ヒントをクリックして getBytes メソッドを作成します。
作成したばかりの 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();
}
java.io.InputStream と java.io.ByteArrayOutputStream のインポート文を追加します。
バイト配列を画像として読み取る
この節では、非公開メソッドを FlowerService クラス本文に追加します。このメソッドでは、JPEG ファイルを表すバイト配列を取得し、 java.awt.Image オブジェクトを返します。バイト配列は、「JPEG ファイルをバイト配列として取得 」の節で作成した getBytes(URL) メソッドによって作成されます。
FlowerService クラス本文で、次の getImage 非公開メソッドを追加します。getImage メソッドの戻り値の型は Image です。このメソッドは、2 つのパラメータを取ります。最初のパラメータは、getBytes メソッドによって作成されるバイト配列です。2 つ目のパラメータは、画像がサムネイルかどうかを示す boolean です。getImage メソッドは、IOException をスローします。
private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {
}
getImage メソッドの本文で、このメソッドがパラメータとして取得するバイト配列から ByteArrayInputStream を作成する行を追加します。
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ByteArrayInputStream から Object を作成する行を追加します。 Object source = bis;
汎用の Object から ImageInputStream を作成する行を追加します。 ImageInputStream iis = ImageIO.createImageInputStream(source);
JPEG ファイルのデコードが可能な、現在登録されているすべての ImageReader から Iterator を作成する行を追加します。
Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
Iterator の次の要素から ImageReader を作成する行を追加します。
ImageReader reader = (ImageReader) readers.next();
デフォルトの画像読み取りパラメータ を作成する行を追加します ( ただし、Image がサムネイルを表す場合は画像読み取りパラメータに 4 対 1 のサブサンプリング処理 を追加)。
ImageReadParam param = reader.getDefaultReadParam();
if (isThumbnail) {
param.setSourceSubsampling(4, 4, 0, 0);
}
最後に、ImageReader オブジェクトを使用して ImageInputStream オブジェクトを読み取り、そのオブジェクトに基づく Image と画像読み取りパラメータを返すコードを追加します。
reader.setInput(iis, true);
return reader.read(0, param);
Ctrl-Shift-I (Mac の場合は ⌘-Shift-I) を押します。「すべてのインポートを修正」ダイアログが開きます。「すべてのインポートを修正」のデフォルトの修正候補をすべて受け入れ、「了解」をクリックします。
これで 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 ファイルのバイト配列のリストの作成
FlowerService のクラス本文の先頭で、すべての花の名前の文字列配列を作成します。
private static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
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;
}
java.util.ArrayList と java.util.List のインポート文を追加します。
getThumbnails の実装
getThumbnails() メソッドを次のように変更します。ここでは、実装コードを追加し、戻り値の型を List から List<Image> に変更します。また、getImage メソッドの isThumbnail のブール値に true を渡します。getThumbnails 実装コードは allFlowers メソッドを呼び出し、すべての JPEG ファイルのバイト配列のリストを作成します 。次に、getThumbnails メソッドは Image の List を作成し、それぞれの花の getImage メソッドを呼び出すことで、その花のバイト配列を Image オブジェクトとして返し、その Image を List に追加します。
@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()
@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 サービスをテストするには、次の手順に従います。
「FlowerAlbumService」ノードを右クリックし、「配備」を選択します。IDE はソースコードをコンパイルし、GlassFish Server Open Source Edition を起動して、プロジェクトの WAR ファイルをサーバーに配備します。「サービス」ウィンドウを開くと、配備された FlowerService がサーバーの「アプリケーション」ノードに表示されます。 重要: GlassFish Server Open Source Edition はバージョン 3.1 b27 以降である必要があります。「スキーマ および WSDL ファイルの変更 」で作成するカスタムスキーマファイルは、以前のバージョンの GlassFish サーバーでは動作しません。「サービス」ウィンドウで GlassFish サーバーのバージョンを確認してください。
プロジェクトの「Web サービス」ノードを展開します。「FlowerService」を右クリックし、「Web サービスをテスト」を選択します。
Web サービスのテストページがブラウザで開きます。「getFlower 」パラメータフィールドに「rose」と入力します。
「getFlower 」ボタンを押します。IDE が、この呼び出しに関する情報をブラウザに表示します。「Method Returned」を見ると、中身が文字化けしていることがわかります。見たいのは記号の羅列ではなく、イメージです。しかし、java.awt.Image は有効なスキーマタイプではないため、バイナリの image/jpeg データを返すようにスキーマファイルを手動で構成する必要があります。これは、次のチュートリアルで行います。
次の手順:
バイナリデータを渡すためのスキーマと WSDL ファイルの変更
nbj2ee
@
netbeans.org
メーリングリスト に登録することによって、NetBeans IDE Java EE 開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。