Remove JavaScript/Kotlin from ScriptEngine documentation
Closes gh-27919
This commit is contained in:
parent
93bc022a46
commit
d4e4250bb1
|
|
@ -210,13 +210,8 @@ The following table shows the templating libraries that we have tested on differ
|
|||
[%header]
|
||||
|===
|
||||
|Scripting Library |Scripting Engine
|
||||
|https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]
|
||||
|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]
|
||||
|===
|
||||
|
||||
TIP: The basic rule for integrating any other script engine is that it must implement the
|
||||
|
|
@ -228,17 +223,8 @@ TIP: The basic rule for integrating any other script engine is that it must impl
|
|||
|
||||
You need to have the script engine on your classpath, the details of which vary by script engine:
|
||||
|
||||
* The https://openjdk.java.net/projects/nashorn/[Nashorn] JavaScript engine is provided with
|
||||
Java 8+. Using the latest update release available is highly recommended.
|
||||
* https://www.jruby.org[JRuby] should be added as a dependency for Ruby support.
|
||||
* https://www.jython.org[Jython] should be added as a dependency for Python support.
|
||||
* `org.jetbrains.kotlin:kotlin-script-util` dependency and a `META-INF/services/javax.script.ScriptEngineFactory`
|
||||
file containing a `org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory`
|
||||
line should be added for Kotlin script support. See
|
||||
https://github.com/sdeleuze/kotlin-script-templating[this example] for more detail.
|
||||
|
||||
You need to have the script templating library. One way to do that for JavaScript is
|
||||
through https://www.webjars.org/[WebJars].
|
||||
|
||||
[[webflux-view-script-integrate]]
|
||||
=== Script Templates
|
||||
|
|
@ -246,7 +232,7 @@ through https://www.webjars.org/[WebJars].
|
|||
|
||||
You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use,
|
||||
the script files to load, what function to call to render templates, and so on.
|
||||
The following example uses Mustache templates and the Nashorn JavaScript engine:
|
||||
The following example uses the Jython Python engine:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
|
@ -255,7 +241,6 @@ Java::
|
|||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
public class WebConfig implements WebFluxConfigurer {
|
||||
|
||||
@Override
|
||||
|
|
@ -266,9 +251,8 @@ Java::
|
|||
@Bean
|
||||
public ScriptTemplateConfigurer configurer() {
|
||||
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
|
||||
configurer.setEngineName("nashorn");
|
||||
configurer.setScripts("mustache.js");
|
||||
configurer.setRenderObject("Mustache");
|
||||
configurer.setEngineName("jython");
|
||||
configurer.setScripts("render.py");
|
||||
configurer.setRenderFunction("render");
|
||||
return configurer;
|
||||
}
|
||||
|
|
@ -280,7 +264,6 @@ Kotlin::
|
|||
[source,kotlin,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
class WebConfig : WebFluxConfigurer {
|
||||
|
||||
override fun configureViewResolvers(registry: ViewResolverRegistry) {
|
||||
|
|
@ -289,9 +272,8 @@ Kotlin::
|
|||
|
||||
@Bean
|
||||
fun configurer() = ScriptTemplateConfigurer().apply {
|
||||
engineName = "nashorn"
|
||||
setScripts("mustache.js")
|
||||
renderObject = "Mustache"
|
||||
engineName = "jython"
|
||||
setScripts("render.py")
|
||||
renderFunction = "render"
|
||||
}
|
||||
}
|
||||
|
|
@ -305,94 +287,7 @@ The `render` function is called with the following parameters:
|
|||
* `RenderingContext renderingContext`: The
|
||||
{spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]
|
||||
that gives access to the application context, the locale, the template loader, and the
|
||||
URL (since 5.0)
|
||||
|
||||
`Mustache.render()` is natively compatible with this signature, so you can call it directly.
|
||||
|
||||
If your templating technology requires some customization, you can provide a script that
|
||||
implements a custom render function. For example, https://handlebarsjs.com[Handlerbars]
|
||||
needs to compile templates before using them and requires a
|
||||
https://en.wikipedia.org/wiki/Polyfill[polyfill] in order to emulate some
|
||||
browser facilities not available in the server-side script engine.
|
||||
The following example shows how to set a custom render function:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
public class WebConfig implements WebFluxConfigurer {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
class WebConfig : WebFluxConfigurer {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
NOTE: Setting the `sharedEngine` property to `false` is required when using non-thread-safe
|
||||
script engines with templating libraries not designed for concurrency, such as Handlebars or
|
||||
React running on Nashorn. In that case, Java SE 8 update 60 is required, due to
|
||||
https://bugs.openjdk.java.net/browse/JDK-8076099[this bug], but it is generally
|
||||
recommended to use a recent Java SE patch release in any case.
|
||||
|
||||
`polyfill.js` defines only the `window` object needed by Handlebars to run properly,
|
||||
as the following snippet shows:
|
||||
|
||||
[source,javascript,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
var window = {};
|
||||
----
|
||||
|
||||
This basic `render.js` implementation compiles the template before using it. A production
|
||||
ready implementation should also store and reused cached templates or pre-compiled templates.
|
||||
This can be done on the script side, as well as any customization you need (managing
|
||||
template engine configuration for example).
|
||||
The following example shows how compile a template:
|
||||
|
||||
[source,javascript,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
function render(template, model) {
|
||||
var compiledTemplate = Handlebars.compile(template);
|
||||
return compiledTemplate(model);
|
||||
}
|
||||
----
|
||||
URL
|
||||
|
||||
Check out the Spring Framework unit tests,
|
||||
{spring-framework-code}/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/script[Java], and
|
||||
|
|
|
|||
|
|
@ -11,13 +11,8 @@ templating libraries on different script engines:
|
|||
[%header]
|
||||
|===
|
||||
|Scripting Library |Scripting Engine
|
||||
|https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn]
|
||||
|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby]
|
||||
|https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython]
|
||||
|https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin]
|
||||
|===
|
||||
|
||||
TIP: The basic rule for integrating any other script engine is that it must implement the
|
||||
|
|
@ -30,18 +25,8 @@ TIP: The basic rule for integrating any other script engine is that it must impl
|
|||
|
||||
You need to have the script engine on your classpath, the details of which vary by script engine:
|
||||
|
||||
* The https://openjdk.java.net/projects/nashorn/[Nashorn] JavaScript engine is provided with
|
||||
Java 8+. Using the latest update release available is highly recommended.
|
||||
* https://www.jruby.org[JRuby] should be added as a dependency for Ruby support.
|
||||
* https://www.jython.org[Jython] should be added as a dependency for Python support.
|
||||
* `org.jetbrains.kotlin:kotlin-script-util` dependency and a `META-INF/services/javax.script.ScriptEngineFactory`
|
||||
file containing a `org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory`
|
||||
line should be added for Kotlin script support. See
|
||||
https://github.com/sdeleuze/kotlin-script-templating[this example] for more details.
|
||||
|
||||
You need to have the script templating library. One way to do that for JavaScript is
|
||||
through https://www.webjars.org/[WebJars].
|
||||
|
||||
|
||||
[[mvc-view-script-integrate]]
|
||||
== Script Templates
|
||||
|
|
@ -49,7 +34,7 @@ through https://www.webjars.org/[WebJars].
|
|||
|
||||
You can declare a `ScriptTemplateConfigurer` bean to specify the script engine to use,
|
||||
the script files to load, what function to call to render templates, and so on.
|
||||
The following example uses Mustache templates and the Nashorn JavaScript engine:
|
||||
The following example uses the Jython Python engine:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
|
@ -58,7 +43,6 @@ Java::
|
|||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
|
|
@ -69,9 +53,8 @@ Java::
|
|||
@Bean
|
||||
public ScriptTemplateConfigurer configurer() {
|
||||
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
|
||||
configurer.setEngineName("nashorn");
|
||||
configurer.setScripts("mustache.js");
|
||||
configurer.setRenderObject("Mustache");
|
||||
configurer.setEngineName("jython");
|
||||
configurer.setScripts("render.py");
|
||||
configurer.setRenderFunction("render");
|
||||
return configurer;
|
||||
}
|
||||
|
|
@ -83,7 +66,6 @@ Kotlin::
|
|||
[source,kotlin,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
class WebConfig : WebMvcConfigurer {
|
||||
|
||||
override fun configureViewResolvers(registry: ViewResolverRegistry) {
|
||||
|
|
@ -92,17 +74,15 @@ Kotlin::
|
|||
|
||||
@Bean
|
||||
fun configurer() = ScriptTemplateConfigurer().apply {
|
||||
engineName = "nashorn"
|
||||
setScripts("mustache.js")
|
||||
renderObject = "Mustache"
|
||||
engineName = "jython"
|
||||
setScripts("render.py")
|
||||
renderFunction = "render"
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
The following example shows the same arrangement in XML:
|
||||
|
||||
XML::
|
||||
+
|
||||
[source,xml,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<mvc:annotation-driven/>
|
||||
|
|
@ -111,12 +91,22 @@ The following example shows the same arrangement in XML:
|
|||
<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 engine-name="jython" render-function="render">
|
||||
<mvc:script location="render.py"/>
|
||||
</mvc:script-template-configurer>
|
||||
----
|
||||
======
|
||||
|
||||
The controller would look no different for the Java and XML configurations, as the following example shows:
|
||||
The render function is called with the following parameters:
|
||||
|
||||
* `String template`: The template content
|
||||
* `Map model`: The view model
|
||||
* `RenderingContext renderingContext`: The
|
||||
{spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]
|
||||
that gives access to the application context, the locale, the template loader, and the
|
||||
URL
|
||||
|
||||
The controller is used to populate the model attributes and specify the view name, as the following example shows:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
|
@ -153,115 +143,6 @@ Kotlin::
|
|||
----
|
||||
======
|
||||
|
||||
The following example shows the Mustache template:
|
||||
|
||||
[source,html,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
<html>
|
||||
<head>
|
||||
<title>{{title}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>{{body}}</p>
|
||||
</body>
|
||||
</html>
|
||||
----
|
||||
|
||||
The render function is called with the following parameters:
|
||||
|
||||
* `String template`: The template content
|
||||
* `Map model`: The view model
|
||||
* `RenderingContext renderingContext`: The
|
||||
{spring-framework-api}/web/servlet/view/script/RenderingContext.html[`RenderingContext`]
|
||||
that gives access to the application context, the locale, the template loader, and the
|
||||
URL (since 5.0)
|
||||
|
||||
`Mustache.render()` is natively compatible with this signature, so you can call it directly.
|
||||
|
||||
If your templating technology requires some customization, you can provide a script that
|
||||
implements a custom render function. For example, https://handlebarsjs.com[Handlerbars]
|
||||
needs to compile templates before using them and requires a
|
||||
https://en.wikipedia.org/wiki/Polyfill[polyfill] to emulate some
|
||||
browser facilities that are not available in the server-side script engine.
|
||||
|
||||
The following example shows how to do so:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@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;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
@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
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
NOTE: Setting the `sharedEngine` property to `false` is required when using non-thread-safe
|
||||
script engines with templating libraries not designed for concurrency, such as Handlebars or
|
||||
React running on Nashorn. In that case, Java SE 8 update 60 is required, due to
|
||||
https://bugs.openjdk.java.net/browse/JDK-8076099[this bug], but it is generally
|
||||
recommended to use a recent Java SE patch release in any case.
|
||||
|
||||
`polyfill.js` defines only the `window` object needed by Handlebars to run properly, as follows:
|
||||
|
||||
[source,javascript,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
var window = {};
|
||||
----
|
||||
|
||||
This basic `render.js` implementation compiles the template before using it. A production-ready
|
||||
implementation should also store any reused cached templates or pre-compiled templates.
|
||||
You can do so on the script side (and handle any customization you need -- managing
|
||||
template engine configuration, for example). The following example shows how to do so:
|
||||
|
||||
[source,javascript,indent=0,subs="verbatim,quotes"]
|
||||
----
|
||||
function render(template, model) {
|
||||
var compiledTemplate = Handlebars.compile(template);
|
||||
return compiledTemplate(model);
|
||||
}
|
||||
----
|
||||
|
||||
Check out the Spring Framework unit tests,
|
||||
{spring-framework-code}/spring-webmvc/src/test/java/org/springframework/web/servlet/view/script[Java], and
|
||||
{spring-framework-code}/spring-webmvc/src/test/resources/org/springframework/web/servlet/view/script[resources],
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ import org.jspecify.annotations.Nullable;
|
|||
* </pre>
|
||||
*
|
||||
* <p><b>NOTE:</b> It is possible to use non thread-safe script engines with
|
||||
* templating libraries not designed for concurrency, like Handlebars or React running on
|
||||
* Nashorn, by setting the {@link #setSharedEngine sharedEngine} property to {@code false}.
|
||||
* templating libraries not designed for concurrency by setting the
|
||||
* {@link #setSharedEngine sharedEngine} property to {@code false}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
|
|
@ -143,7 +143,7 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig {
|
|||
* for each request, else the same instance will be reused.
|
||||
* This flag should be set to {@code false} for those using non thread-safe script
|
||||
* engines with templating libraries not designed for
|
||||
* concurrency, like Handlebars or React running on Nashorn for example.
|
||||
* concurrency.
|
||||
* <p>When this flag is set to {@code false}, the script engine must be specified using
|
||||
* {@link #setEngineName(String)}. Using {@link #setEngine(ScriptEngine)} is not
|
||||
* possible because multiple instances of the script engine need to be created for
|
||||
|
|
|
|||
|
|
@ -58,10 +58,6 @@ import org.springframework.web.server.ServerWebExchange;
|
|||
* {@link ScriptTemplateConfig} bean in the web application context and using
|
||||
* it to obtain the configured properties.
|
||||
*
|
||||
* <p>The Nashorn JavaScript engine requires Java 8+ and may require setting the
|
||||
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
||||
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ import org.jspecify.annotations.Nullable;
|
|||
* </pre>
|
||||
*
|
||||
* <p><b>NOTE:</b> It is possible to use non thread-safe script engines with
|
||||
* templating libraries not designed for concurrency, like Handlebars or React running on
|
||||
* Nashorn, by setting the {@link #setSharedEngine sharedEngine} property to {@code false}.
|
||||
* templating libraries not designed for concurrency by setting the
|
||||
* {@link #setSharedEngine sharedEngine} property to {@code false}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.2
|
||||
|
|
@ -144,7 +144,7 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig {
|
|||
* When set to {@code false}, use thread-local {@link ScriptEngine} instances instead
|
||||
* of one single shared instance. This flag should be set to {@code false} for those
|
||||
* using non thread-safe script engines with templating libraries not designed for
|
||||
* concurrency, like Handlebars or React running on Nashorn for example.
|
||||
* concurrency.
|
||||
* <p>When this flag is set to {@code false}, the script engine must be specified using
|
||||
* {@link #setEngineName(String)} or {@link #setEngineSupplier(Supplier)}.
|
||||
* Using {@link #setEngine(ScriptEngine)} is not possible because multiple instances
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView;
|
|||
* {@link ScriptTemplateConfig} bean in the web application context and using
|
||||
* it to obtain the configured properties.
|
||||
*
|
||||
* <p>The Nashorn JavaScript engine requires Java 8+ and may require setting the
|
||||
* {@code sharedEngine} property to {@code false} in order to run properly. See
|
||||
* {@link ScriptTemplateConfigurer#setSharedEngine(Boolean)} for more details.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.2
|
||||
|
|
|
|||
|
|
@ -1201,9 +1201,7 @@
|
|||
<xsd:documentation><![CDATA[
|
||||
When set to false, use thread-local ScriptEngine instances instead of one single shared
|
||||
instance. This flag should be set to false for those using non thread-safe script engines
|
||||
with templating libraries not designed for concurrency, like Handlebars or React
|
||||
running on Nashorn for example. In this case, Java 8u60 or greater is required due to
|
||||
this bug: https://bugs.openjdk.java.net/browse/JDK-8076099.
|
||||
with templating libraries not designed for concurrency.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
|
|
|||
Loading…
Reference in New Issue