Thymeleaf 3 から JavaScript (というよりインライン処理)の中でエスケープせずに文字列を出力できるようになっています。
[[...]]
の代わりに[(...)]
を使えば良いです。
例
HTML
<script th:inline="javascript">/*<![CDATA[*/
var foo = /*[(${foo})]*/ {"bar":"drei","baz":"]]\u003e"\n'<\u002fscript\u003e"};
/*]]>*/</script>
Controller (Spring)
@GetMapping("/")
public Object index(Model model) throws IOException {
final MyForm myForm = new MyForm("", "'\"&</script>]]>", Optional.of(LocalDateTime.now()));
model.addAttribute("foo", this.objectMapper.writeValueAsString(myForm));
return "index";
}
=> 出力1
<script>/*<![CDATA[*/
var contextPath = "\/";
var foo = {"baz":"","cux":"'\"&<\u002Fscript\u003E]]\u003E","datetime":"2017-10-16T23:26"};
/*]]>*/</script>
なお、 Thymeleaf にオブジェクトをそのまま渡してシリアライズさせた場合、 LocalDate 等(JSR-310 関係)はよろしく変換してくれますが、 Optional は未対応のようです。
おまけ: build.gradle の依存関係設定
Spring Boot 1.5 系の場合、 spring-boot-starter-thymeleaf の参照先は Thymeleaf 2 なので別途依存関係を指定してやる必要があります。
def thymeleafVersion = '3.0.7.RELEASE'
// https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4
compile group: 'org.thymeleaf', name: 'thymeleaf-spring4', version: thymeleafVersion
// https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf
compile group: 'org.thymeleaf', name: 'thymeleaf', version: thymeleafVersion
あとは AutoConfiguration が効いてよろしくやってくれます。
-
この例では ObjectMapper をカスタマイズして
/
と>
をエスケープしています。</script>
タグと]]>
を回避するためです。 ↩