Thymeleafで画像表示をする為に試したり調べたりした内容をまとめる。
1. Staticフォルダ配下に格納した画像を参照
このパターンが一番シンプル。
画像ファイル(test.jpg)を下記のように配置したとする。
src.main.resorces
|-static
|-test.jpg
test.jpgを画面に表示したい場合、htmlを下記の様に記載する。
<img th:src="@{test.jpg}">
2. リソースハンドラを設定
外から参照できるのは、デフォルトではStaticフォルダ直下のファイルである。
クラスパスを追加する事で、任意フォルダ内のファイルにも参照できるようになる。
プロジェクト外のフォルダも設定することができるので、簡易的な画像ビュー機能を
作成することもできる。
書き方は下記stackoverflow質問者様のコードを参考にした。
3. 画像参照用のAPIメソッド
画像Entityを返すメソッドを作成することで画像表示が可能である。
クラスパスの変更を行わずに、任意フォルダ配下の画像を参照できるようになる。
@GetMapping("/images/{imageName:.+}")
public ResponseEntity<Resource> downloadImage(@PathVariable("imageName") String imageName) {
final Path targetPath = storageService.load(imageName);
if (!Files.exists(targetPath)) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(new PathResource(targetPath));
}
storageService.load(imageName)
は、「/ファイル保存用ディレクトリ/imageName」のPathデータを返却する。
Thymeleaf側で下記のように記載すれば、画像が表示される。
<img th:src="@{'/images/' + ${imageName}}">
下記stackoverflowの回答者様コードを参考にした。
オマケ:Thymeleafの変数式に関して
1. 文字列と変数を組み合わせたい場合
例えばformのactionを記載する場合、以下のようになる。
<form th:action="@{'/testPath/' + ${test}}" method="post">
2. 変数式を引数に使いたい時
変数Mapに対して変数Keyを用いて値を参照する等、変数式内の引数として
新たな変数式を使いたい時がある。
そのさいは下記のように記載する。
${testMap.get(__${testKey}__)}
プリプロセッシング式と言い、アンダースコアを2つ前後に記載することで
先に評価されるようになる。
3. 文字列にドットを含む場合の注意点
Thymeleafでファイル名のようなドットを含む文字列が変数式で評価される際、
文字列ではなくオブジェクトとして評価されるようだ。
画面表示のみであれば問題ない。
一方、プリプロセッシング式として評価される場合、下記のようなエラーが出力される。
EL1007E: Property or field 'jpg' cannot be found on null
ドットを含む文字列を、オブジェクトではなく文字列として評価させる必要がある。
下記のように記載することで対応が可能である。
<div th:with="key=|'${testKey}'|">
<p>[[${testMap.get(__${key}__)}]]</p>
</div>
|を前後に記載した書き方は、リテラル置換と呼ばれる。
リテラル置換によって文字列の中に変数式を含める事が出来る。
th:withは、ブロック内にて有効な変数を定義できる。
文字列として評価されるように''で囲んだ状態で変数を定義することで、
ドットを含むKey値でMapから値を取得できるようになる。