ObjectOutputStreamを使ってファイルのやり取りをSpring Bootで実装する

ObjectOutputStreamObjectInputStreamを使うことで、Serializable JavaオブジェクトのHTTPを通した送信、受信ができる。オブジェクトにbyte[]が含まれていれば、バイナリファイルのアップロードとダウンロードもできることになる。

ObjectOutputStream/ObjectInputStreamでJavaオブジェクトを送受信する場合、サーバサイドだけでなくクライアントもJava実装を強いられるため、複数のクライアントが対応しようとするときの障壁になる。基本は、JSONでのやりとりやmultipart/form-data形式で送受信した方がブラウザをはじめとして多種多様なクライアントとのやり取りが簡単になるので、Javaオブジェクトを送受信しないほうがいい。

今回、他社に作られたObjectOutputStream/ObjectInputStreamで送受信するシステムと接続することになり、こちらの環境でその外部システムのスタブを作ることになったので、それをSpring Bootで実装してみた。

version
Spring Boot 1.4.0

ファイルの送受信の種類

ObjectOutputStream/ObjectInputStreamで作るのは今回のような前提がない限り勧められないので、Spring Bootでの実装に移る前に、送受信の種類を一覧にしておく。特に理由がない限り各項目の上位に記載されている方法から順に実装を検討するといい。

送信

  • multipart/form-data形式(HTML)
  • Base64 EncodeしてJSONにセットする
  • ObjectOutputStream/ObjectInputStream

受信

  • ダウンロード形式(Content-Disposition: attachment)
  • Base64 EncodeしてJSONにセットする
  • ObjectOutputStream/ObjectInputStream

ダウンロード形式ではファイルのバイナリデータ以外にデータを送ることができないが、ファイル名であればContent-Dispositionヘッダにセットされる。

参考:Spring Bootで日本語ファイル名のファイルダウンロード

ファイル名以外にも大量に情報を受信するのには向かないが、一つ二つ追加したいくらいであれば独自ヘッダを定義してヘッダに情報を書くのもいいだろう。

Spring Bootでの実装

Spring Bootでのサーバサイド実装

※サンプルのためエラーは全て握りつぶす。
new ObjectInputStream(req.getInputStream())readObject(), new ObjectOutputStream(res.getOutputStream())writeObject(ret)がObjectOutputStream/ObjectInputStreamを使う上でキーになるコード。

URLConnectionを使ったクライアント実装

Java標準ライブラリのURLConnectionを使ってクライアントを書く。
uc.setRequestProperty("Content-Type", "application/octet-stream");がないと、サーバでreq.getInputStream()をしたときにEOFExceptionが発生してしまった。

-Java
-