SpringMVCで画像の入出力をするだけ

# 諸注意
SpringMVCを用いて、画像をアップロードし、それを出力したい、との要望があったためサンプルとして作成。
あくまでサンプルレベルなので、Validationは無視してるし、拡張子の確認もしていない。
なんなら画像をアップロードはできるけど、保存処理はしてない。
とりあえず実行してみたい人向け。

# 実行環境
実行環境は下記の通り

| 名称 | バージョン等 |
|:-:|:-:|
| IDE  |sts-4.0.1.RELEASE |
|Java  | Java1.8  |
|SpringFrameworkBoot   |2.1.9   |
|SpringDependencyManagement   |1.0.8   |

# 動作の流れ
作成するサンプルは下記の通り分類できる(FirstApplicationクラスは除く)

　①　画像アップロード用のHTML
　②　画像データを格納するフォーム
　③　画像データの受け渡しするコントローラー
　④　アップロードされた画像を表示するHTML

# 実際のコード

## ①に該当するhtml
```html:upload.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8" />
    <title>upload.html</title>
</head>

<body>
    <!-- formにenctypeを設定しない場合、画像の中身が送信されないため注意 -->
    <form th:action="@{/upload}" th:object="${imageForm}" method="post" enctype="multipart/form-data">
        ファイルを選択： <input type="file" th:field="*{image}" /><br /> <input type="submit" value="送信する" />
    </form>
</body>

</html>
```

ポイントは``enctype="multipart/form-data"``
これが無い場合はコントローラーで中身のデータを受け取ることができない(ファイル名しか受け取れない)


## ②に該当するフォーム
```java:imageForm.java
package com.practice.demo_spring.web;

import org.springframework.web.multipart.MultipartFile;

public class ImageForm {

	private MultipartFile image;

	public MultipartFile getImage() {
		return image;
	}

	public void setImage(MultipartFile image) {
		this.image = image;
	}

}
```

なんてことのないフォームクラス。

## ③に該当するコントローラー
```java:UploadController.java
package com.practice.demo_spring.web;

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UploadController {
	
	@ModelAttribute
	public ImageForm setForm() {
		return new ImageForm();
	}
	
	/**
	 * まずlocalhost:8080/firstでupload.htmlにアクセスするよう設定
	 * @return　upload.html
	 */
	@RequestMapping("/first")
	public String first() {
		return "upload";
	}
	
	
	/**
	 * アップロードされた画像データを取得し、base64でエンコードする
	 * エンコードしたものを文字列に変更(同時に拡張子をここではjpegと指定)し次のhtmlに受け渡す
	 * @param imageForm アップロードされたデータ
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/upload")
	public String upload(ImageForm imageForm, Model model) throws Exception {
		System.out.println(imageForm.getImage().getSize());
		StringBuffer data = new StringBuffer();
		String base64 = new String(Base64.encodeBase64(imageForm.getImage().getBytes()),"ASCII");
		data.append("data:image/jpeg;base64,");
		data.append(base64);
		model.addAttribute("base64image",data.toString());
		return "express";
	}

}
```
処理としては、
① imageFormに格納された画像データを取得し、byteの配列にする
② それをbase64にエンコードし、且つString型に変更する
③ 先に変更したStringと"data:image/jpeg;base64,"を組み合わせて``<img ht:src="">``で指定できる形にする
以上の流れを踏んでいる

## ④に該当するhtml
```html:express.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <title>express.html</title>
  </head>
  <body>
      画像は<img th:src="${base64image}"/>です
  </body>
</html>
```
ここではコントローラークラスから受け取った文字列を``src``に指定し、表示させている


# デモ
https://localhost:8080/first にアクセス
![2019-10-17_10h42_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318745/e8f3fb12-2515-2d33-fea4-fd01dddb1af3.png)

適当に画像データを選択
![2019-10-17_11h00_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318745/fa71f3c4-1fdf-d7f1-c255-c626635ea6d2.png)

送信ボタン押下で、アップロードした画像が表示される
![2019-10-17_11h01_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318745/5a609972-05d8-8d99-e077-4dcb41d0c0c4.png)


以上とりあえずサンプルだけ作成しました。
後はお好みでチェックやら何やら機能を付けてください。