サーブレットでのイメージの受け取り
続いて、送信されたイメージ(BufferedIMage
オブジェクト)をサーブレット側で受け取る処理saveImageToFile
メソッドを考えてみましょう。
private void saveImageToFile(HttpServletRequest request) { ServletContext application = this.getServletContext(); String fpath = application.getRealPath("WEB-INF/" + imgpath); ServletInputStream input = null; try { input = request.getInputStream(); BufferedImage img = ImageIO.read(input); ImageIO.write(img,"jpeg",new File(fpath)); } catch (IOException ex) { ex.printStackTrace(); } finally { try { input.close(); } catch (Exception ex2) { ex2.printStackTrace(); } } }
ここでは、まずServletContext
インスタンスを取得し、そこからgetRealPath
で保存するファイルのフルパスを得ておきます。いわば、下準備です。
ServletContext application = this.getServletContext(); String fpath = application.getRealPath("WEB-INF/" + imgpath);
続いて、HttpServletRequest
からServletInputStream
を取得します。このストリームから、送信されてきたイメージのデータが得られるわけです。
input = request.getInputStream();
後は、ImageIO
を使ってイメージを読み込み、ファイルに出力するだけです。ImageIO.read
でInputStream
からイメージを読み込み、これをImageIO.write
でファイルに書き出します。
BufferedImage img = ImageIO.read(input);
ImageIO.write(img,"jpeg",new File(fpath));
ImageIO.read
は、このようにストリームからイメージをそのまま取り出すこともできるのです。これを利用すれば、送信されたBufferedImage
をストリームから取り出すのは訳ありません。
サーブレットからアプレットへの送信
今度は、逆を行いましょう。サーブレットでファイルから読み込んだBufferedImage
を送信しアプレットで受け取る、という処理です。といっても、もちろん勝手にサーブレットから送ったりするわけではなくて、アプレットからサーブレットに「イメージを送れ」と要求を出し、それに応じてサーブレットがデータを送信し、それをアプレットが受け取って表示するわけです。
まずは、アプレット側のイメージ読み込み処理loadImage
メソッドから作成しましょう。
private void loadImage(ActionEvent ev){ ImageInputStream imgin = null; InputStream in = null; try { URL url = new URL(servpath); HttpURLConnection connect = (HttpURLConnection)url.openConnection(); connect.setDoInput(true); connect.setRequestMethod("GET"); in = connect.getInputStream(); imgin = ImageIO.createImageInputStream(in); BufferedImage im = ImageIO.read(imgin); panel.setDrawImage(im); } catch (Exception ex) { ex.printStackTrace(); } finally { try { imgin.close(); connect.disconnect(); } catch (Exception ex2) { ex2.printStackTrace(); } } }
イメージの送信の逆ですが、こちらの方が若干簡単になります。まず、読み込むイメージのURLと、HttpURLConnection
インスタンスの作成を行います。
URL url = new URL(servpath);
HttpURLConnection connect =
(HttpURLConnection)url.openConnection();
これは送信の場合と同じですから分かりますね。続いて、
connect.setDoInput(true); connect.setRequestMethod("GET");
そしてストリーム関係の作成です。既に先ほどImageIO.read
を使ってread
する方法は学んでいますから、これをそのまま使うだけです。
imgin = ImageIO.createImageInputStream(in); BufferedImage im = ImageIO.read(imgin);
ImageIO.createImageInputStream
でImageInputStream
を作成し、これを利用してImageIO.read
からイメージを読み込みます。後は、ImagePanel
のsetDrawImage
を呼び出して、受け取ったイメージを表示させるだけです。
サーブレットでのイメージの送信
では、イメージを送信しているサーブレット側の処理はどうなるでしょうか。loadImageFromFile
メソッドとして定義する内容を作成しましょう。
public void loadImageFromFile(HttpServletResponse response){ ServletContext application = this.getServletContext(); String fpath = application.getRealPath("WEB-INF/" + imgpath); ServletOutputStream sos = null; try { response.setContentType("image/jpeg"); sos = response.getOutputStream(); BufferedImage img = ImageIO.read(new File(fpath)); ImageOutputStream ios = ImageIO.createImageOutputStream(sos); ImageIO.write(img,"JPEG",ios); } catch(IOException ex) { ex.printStackTrace(); } finally { try { sos.close(); } catch(IOException ex2) {} } }
先のsaveImageToFile
と同様に、まずはServletContext
と読み込むファイルのフルパスをgetRealPath
で取得しておきます。そして送信するコンテンツの種類を設定します。
response.setContentType("image/jpeg");
ここではJPEGのイメージとして送信をしますので、setContentType
で"image/jpeg"にしておきます。ここまでで下準備は完了です。
では、出力用のストリームを用意していきます。まずHttpServletResponse
からOutputStream
を取得し、ImageIO
を使ってImageOutputStream
を作成して、これにイメージを送信します。
sos = response.getOutputStream(); BufferedImage img = ImageIO.read(new File(fpath)); ImageOutputStream ios = ImageIO.createImageOutputStream(sos); ImageIO.write(img,"JPEG",ios);
ストリームを準備し、ImageIO
でイメージ用のストリームを作って読み書きする、という基本的な流れは、読み込みも書き出しもほぼ同じです。この流れが分かれば、サーブレット側の処理はそう悩むことはないでしょう。
まとめ
アプレット/サーブレット間でイメージをやり取りするためには、アプレットとサーブレットのそれぞれの処理方法を頭に入れておく必要があります。注意するポイントを整理すると次のようになります。
- アプレットでは、
HttpURLConnection
の基本的な使い方を理解する。 - サーブレットでは、
HttpServletRequest
またはHttpServletResponse
から入出力のストリームを取得し利用する。 - いずれの場合も、
ImageIO
からイメージ用のストリームを用意し、同じくImageIO
のread
/write
でストリームにイメージを送受する。
ImageIO
のおかげで、イメージ関係のストリームの作成や入出力などが実に簡単になっていることが実感できるでしょう。アプレットからサーブレットを利用できるようになれば、アプレットもいろいろと応用できるようになるはずです。フロントエンドとしてのアプレットを見直すきっかけとなれば幸いです。