『ものぐさ Jersey』的なやつが好評のようなので、その RESTEasy 編。
いきなりで恐縮だが、REST なウェブサービスを作っている際に画像も REST 的に取り扱いたいときがある。
要するに適当なエンドポイントを叩くと画像ファイルが返ってくる、みたいなやつだ。
サーブレットで実現するのが一番簡単なようなんだが、サーブレットを使わない方向でチャレンジする。
リンクした記事は jsp で書いてあるが、ちなみにサーブレットで書き直すとこんな感じ↓になる。
あっさり成功。
で、RESTEasy 。
まずは公式ドキュメントのチェック。
レスポンスを適当に加工すれば、なんとかなるだろうくらいに思って調べてみた。
なんだが…
なんでしょう、この突き放された感じ(笑)。
jakarta.ws.rs.core.StreamingOutput を使って自分で実装しろ的なことが書かれている。
いや、そんなことをするくらいならば、サーブレットのやつそのまま使いたいかなあ(困惑)。
アウトプットストリーム系を使って、とりあえずバイト列を返す
他の人がどうやっているかよくわからないのだが、まずはシンプルに攻める。
(公式ドキュメントのサジェスチョンを尊重して)バイト列を生成して、そいつを ByteArrayOutputStream にセットし、さらにそれを Response の中(Entity とかいうみたいだ)に入れ込んで REST っぽく返す、と以下のような感じになる。
@Path("/octet")
public class OctetServer {
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response sendOctet() throws IOException{
byte[] byteData = "123456789ABCDE".getBytes();
ByteArrayOutputStream output = new ByteArrayOutputStream();
output.write(byteData);
return Response.ok(output.toByteArray(), MediaType.APPLICATION_OCTET_STREAM).build();
}
}
これで curl で (コンテクスト)/octet を叩くと、もちろん 123456789ABCDE がバイナリで返ってくる。
ブラウザからアクセスすると octet というファイルを落としてくれるが、中身は当然 123456789ABCDE だ。
これで、第一段階はクリア…
と思っていたが、コード見直すと、バイト列をストリームにセットした後、さらにバイト列に戻す、というバカっぽいことをやっている(苦笑)。
バイト列をエンティティとしても同じ
だから、上のサンプルはもうちょっと簡単になる。
具体的には、
return Response.ok(output.toByteArray(), MediaType.APPLICATION_OCTET_STREAM).build();
は、
return Response.ok(byteData, MediaType.APPLICATION_OCTET_STREAM).build();
としても変わらない。
もちろん、その上の2行は全く不要。
とりあえず、バイナリのデータを返すだけであれば、アウトプットストリーム系は不要で返したいデータのバイト列を response のエンティティにセットすればいいだけのようだ。
指定した画像などを返したければ、path parameter を設定してデータベースから検索して云々とやれば、実現できそう。


