スクリプトビュー

Spring Framework には、Spring MVCJSR-223 (英語) Java スクリプトエンジン上で実行できるテンプレートライブラリと使用するための組み込みの統合があります。さまざまなスクリプトエンジンで次のテンプレートライブラリをテストしました。

スクリプトライブラリ スクリプトエンジン

Handlebars (英語)

Nashorn (英語)

Mustache (英語)

Nashorn (英語)

React (英語)

Nashorn (英語)

EJS (英語)

Nashorn (英語)

ERB (英語)

JRuby (英語)

文字列テンプレート (英語)

Jython (英語)

Kotlin スクリプトテンプレート [GitHub] (英語)

Kotlin (英語)

他のスクリプトエンジンを統合するための基本的なルールは、ScriptEngine および Invocable インターフェースを実装する必要があるということです。

要件

クラスパスにスクリプトエンジンが必要です。詳細はスクリプトエンジンによって異なります。

  • Nashorn (英語) JavaScript エンジンには Java 8+ が付属しています。利用可能な最新の更新リリースを使用することを強くお勧めします。

  • JRuby (英語) は、Ruby サポートの依存関係として追加する必要があります。

  • Jython (英語) は、Python サポートの依存関係として追加する必要があります。

  • Kotlin スクリプトをサポートするには、org.jetbrains.kotlin:kotlin-script-util 依存関係と org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory 行を含む META-INF/services/javax.script.ScriptEngineFactory ファイルを追加する必要があります。詳細については、この例 [GitHub] (英語) を参照してください。

スクリプトテンプレートライブラリが必要です。JavaScript でこれを行う 1 つの方法は、WebJars (英語) を使用することです。

スクリプトテンプレート

ScriptTemplateConfigurer Bean を宣言して、使用するスクリプトエンジン、ロードするスクリプトファイル、テンプレートをレンダリングするために呼び出す関数などを指定できます。次の例では、Mustache テンプレートと Nashorn JavaScript エンジンを使用しています。

  • Java

  • Kotlin

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.scriptTemplate();
	}

	@Bean
	public ScriptTemplateConfigurer configurer() {
		ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
		configurer.setEngineName("nashorn");
		configurer.setScripts("mustache.js");
		configurer.setRenderObject("Mustache");
		configurer.setRenderFunction("render");
		return configurer;
	}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.scriptTemplate()
	}

	@Bean
	fun configurer() = ScriptTemplateConfigurer().apply {
		engineName = "nashorn"
		setScripts("mustache.js")
		renderObject = "Mustache"
		renderFunction = "render"
	}
}

次の例は、XML での同じ配置を示しています。

<mvc:annotation-driven/>

<mvc:view-resolvers>
	<mvc:script-template/>
</mvc:view-resolvers>

<mvc:script-template-configurer engine-name="nashorn" render-object="Mustache" render-function="render">
	<mvc:script location="mustache.js"/>
</mvc:script-template-configurer>

次の例に示すように、コントローラーは Java 構成と XML 構成で同じように見えます。

  • Java

  • Kotlin

@Controller
public class SampleController {

	@GetMapping("/sample")
	public String test(Model model) {
		model.addAttribute("title", "Sample title");
		model.addAttribute("body", "Sample body");
		return "template";
	}
}
@Controller
class SampleController {

	@GetMapping("/sample")
	fun test(model: Model): String {
		model["title"] = "Sample title"
		model["body"] = "Sample body"
		return "template"
	}
}

次の例は、Mustache テンプレートを示しています。

<html>
	<head>
		<title>{{title}}</title>
	</head>
	<body>
		<p>{{body}}</p>
	</body>
</html>

レンダリング関数は、次のパラメーターで呼び出されます。

  • String template: テンプレートの内容

  • Map model: ビューモデル

  • RenderingContext renderingContext: アプリケーションコンテキスト、ロケール、テンプレートローダー、URL へのアクセスを提供する RenderingContext (Javadoc) (5.0 以降)

Mustache.render() はこの署名とネイティブに互換性があるため、直接呼び出すことができます。

テンプレートテクノロジでカスタマイズが必要な場合は、カスタムレンダリング機能を実装するスクリプトを提供できます。例: Handlerbars (英語) は、テンプレートを使用する前にコンパイルする必要があり、サーバー側のスクリプトエンジンでは利用できないブラウザー機能をエミュレートするためにポリフィル [Mozilla] が必要です。

次の例は、その方法を示しています。

  • Java

  • Kotlin

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.scriptTemplate();
	}

	@Bean
	public ScriptTemplateConfigurer configurer() {
		ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
		configurer.setEngineName("nashorn");
		configurer.setScripts("polyfill.js", "handlebars.js", "render.js");
		configurer.setRenderFunction("render");
		configurer.setSharedEngine(false);
		return configurer;
	}
}
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer {

	override fun configureViewResolvers(registry: ViewResolverRegistry) {
		registry.scriptTemplate()
	}

	@Bean
	fun configurer() = ScriptTemplateConfigurer().apply {
		engineName = "nashorn"
		setScripts("polyfill.js", "handlebars.js", "render.js")
		renderFunction = "render"
		isSharedEngine = false
	}
}
Nashorn で実行されている Handlebars や React (参考: JavaScript フロントエンドフレームワークの比較 [Qiita] ) など、同時実行用に設計されていないテンプレートライブラリで非スレッドセーフスクリプトエンジンを使用する場合は、sharedEngine プロパティを false に設定する必要があります。その場合、このバグ (英語) のため、Java SE 8 update 60 が必要ですが、通常は最新の Java SE パッチリリースを使用することをお勧めします。

polyfill.js は、次のように、Handlebars が適切に実行するために必要な window オブジェクトのみを定義します。

var window = {};

この基本的な render.js 実装は、テンプレートを使用する前にコンパイルします。本番環境向けの実装では、再利用されたキャッシュ済みテンプレートまたはプリコンパイル済みテンプレートも保存する必要があります。スクリプト側でそれを行うことができます(そして、必要なカスタマイズを処理します。たとえば、テンプレートエンジンの構成を管理します)。次の例は、その方法を示しています。

function render(template, model) {
	var compiledTemplate = Handlebars.compile(template);
	return compiledTemplate(model);
}

その他の構成例については、Spring Framework 単体テスト、Java [GitHub] (英語) リソース [GitHub] (英語) を参照してください。