今回実装するのは以下のような機能です。
・写真をアップロードするAPIを作成する
・MultipartFileを利用せず、バイナリでデータを受け取る
・Java経由で指定ディレクトリにファイルを出力する
・ファイル名は年月日時分秒を自動採番(アップロード元の名前は利用しない)
・バイナリの情報を取得して画像の圧縮形式(拡張子)を取得する
この部分は以下の情報を参考にさせていただきました。
→バイナリーデータから画像の種類を判別する
修正するファイル
Controller
com.example.UsersController.java
@RequestMapping(path = "/users/upload", method = RequestMethod.POST)
public void upload(InputStream req) throws IOException {
ByteArrayOutputStream byteos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int size = 0;
while ((size = req.read(buf, 0, buf.length)) != -1) {
byteos.write(buf, 0, size);
}
String filename = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now());
Path uploadfile = Paths.get("Users/demo-kusa/image" + filename
+ "." + getFormat(byteos.toByteArray()));
try (OutputStream os = Files.newOutputStream(uploadfile, StandardOpenOption.CREATE)) {
os.write(byteos.toByteArray());
} catch (IOException ex) {
System.err.println(ex);
}
}
ImageTypeCheck.javaはリンク元の記事を参照
(私は少し手を加えていますが、このままでも動作はしました)
ImageType.java
バイナリデータを送付する場合、curlなどhttpクライアント系コマンド、javascriptで作り込み、RESTクライアントなどいくつか手段がありますが、今回はPostmanを利用しました。
ここまで書いて、ControllerにおいてIOExceptionをtry、throwsさせていることに気が付きました。後日リファクタリングします。目的があるとは言ってもByteArrayOutputStreamを経由することで無駄にリソースを消費しているため、見直します。。
github kaikusakari/spring_crud