提交 e86b937f 编写于 作者: S Sebastien Deleuze

Leverage new Kotlin script templating support

As of 1.3.40, Kotlin now provides a kotlin-scripting-jsr223-embeddable
dependency which:
 - Fixes classloading related issues
 - Provides out of the box JSR 223 support
 - Is compatible with Spring Boot Fat Jar mechanism

This commit updates Spring Framework tests and documentation accordingly.

Closes gh-23165
上级 cfb41489
...@@ -55,10 +55,9 @@ dependencies { ...@@ -55,10 +55,9 @@ dependencies {
testCompile("org.eclipse.jetty:jetty-servlet") testCompile("org.eclipse.jetty:jetty-servlet")
testCompile("org.eclipse.jetty:jetty-reactive-httpclient:1.0.3") testCompile("org.eclipse.jetty:jetty-reactive-httpclient:1.0.3")
testCompile("com.squareup.okhttp3:mockwebserver:3.14.2") testCompile("com.squareup.okhttp3:mockwebserver:3.14.2")
testCompile("org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}")
testCompile(project(":spring-core-coroutines")) testCompile(project(":spring-core-coroutines"))
testRuntime("org.jetbrains.kotlin:kotlin-script-util:${kotlinVersion}") testCompile("org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}")
testRuntime("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}") testRuntime("org.jetbrains.kotlin:kotlin-scripting-jsr223-embeddable:${kotlinVersion}")
testRuntime("org.jruby:jruby:9.2.7.0") testRuntime("org.jruby:jruby:9.2.7.0")
testRuntime("org.python:jython-standalone:2.7.1") testRuntime("org.python:jython-standalone:2.7.1")
testRuntime("org.synchronoss.cloud:nio-multipart-parser:1.1.0") testRuntime("org.synchronoss.cloud:nio-multipart-parser:1.1.0")
......
...@@ -20,7 +20,6 @@ import java.util.HashMap; ...@@ -20,7 +20,6 @@ import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
...@@ -41,7 +40,6 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -41,7 +40,6 @@ import static org.assertj.core.api.Assertions.assertThat;
*/ */
public class KotlinScriptTemplateTests { public class KotlinScriptTemplateTests {
@Ignore
@Test @Test
public void renderTemplateWithFrenchLocale() throws Exception { public void renderTemplateWithFrenchLocale() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
...@@ -51,7 +49,6 @@ public class KotlinScriptTemplateTests { ...@@ -51,7 +49,6 @@ public class KotlinScriptTemplateTests {
assertThat(response.getBodyAsString().block()).isEqualTo("<html><body>\n<p>Bonjour Foo</p>\n</body></html>"); assertThat(response.getBodyAsString().block()).isEqualTo("<html><body>\n<p>Bonjour Foo</p>\n</body></html>");
} }
@Ignore
@Test @Test
public void renderTemplateWithEnglishLocale() throws Exception { public void renderTemplateWithEnglishLocale() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
...@@ -61,7 +58,6 @@ public class KotlinScriptTemplateTests { ...@@ -61,7 +58,6 @@ public class KotlinScriptTemplateTests {
assertThat(response.getBodyAsString().block()).isEqualTo("<html><body>\n<p>Hello Foo</p>\n</body></html>"); assertThat(response.getBodyAsString().block()).isEqualTo("<html><body>\n<p>Hello Foo</p>\n</body></html>");
} }
@Ignore
@Test @Test
public void renderTemplateWithoutRenderFunction() throws Exception { public void renderTemplateWithoutRenderFunction() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
......
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
...@@ -73,8 +73,7 @@ dependencies { ...@@ -73,8 +73,7 @@ dependencies {
testCompile("io.reactivex:rxjava-reactive-streams:${rxjavaAdapterVersion}") testCompile("io.reactivex:rxjava-reactive-streams:${rxjavaAdapterVersion}")
testCompile("io.reactivex.rxjava2:rxjava:${rxjava2Version}") testCompile("io.reactivex.rxjava2:rxjava:${rxjava2Version}")
testCompile("org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}") testCompile("org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}")
testRuntime("org.jetbrains.kotlin:kotlin-script-util:${kotlinVersion}") testRuntime("org.jetbrains.kotlin:kotlin-scripting-jsr223-embeddable:${kotlinVersion}")
testRuntime("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}")
testRuntime("org.jruby:jruby:9.2.7.0") testRuntime("org.jruby:jruby:9.2.7.0")
testRuntime("org.python:jython-standalone:2.7.1") testRuntime("org.python:jython-standalone:2.7.1")
testRuntime("org.webjars:underscorejs:1.8.3") testRuntime("org.webjars:underscorejs:1.8.3")
......
...@@ -22,7 +22,6 @@ import java.util.Map; ...@@ -22,7 +22,6 @@ import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
...@@ -56,7 +55,6 @@ public class KotlinScriptTemplateTests { ...@@ -56,7 +55,6 @@ public class KotlinScriptTemplateTests {
this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.webAppContext); this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.webAppContext);
} }
@Ignore
@Test @Test
public void renderTemplateWithFrenchLocale() throws Exception { public void renderTemplateWithFrenchLocale() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
...@@ -66,7 +64,6 @@ public class KotlinScriptTemplateTests { ...@@ -66,7 +64,6 @@ public class KotlinScriptTemplateTests {
assertThat(response.getContentAsString()).isEqualTo("<html><body>\n<p>Bonjour Foo</p>\n</body></html>"); assertThat(response.getContentAsString()).isEqualTo("<html><body>\n<p>Bonjour Foo</p>\n</body></html>");
} }
@Ignore
@Test @Test
public void renderTemplateWithEnglishLocale() throws Exception { public void renderTemplateWithEnglishLocale() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
...@@ -76,7 +73,6 @@ public class KotlinScriptTemplateTests { ...@@ -76,7 +73,6 @@ public class KotlinScriptTemplateTests {
assertThat(response.getContentAsString()).isEqualTo("<html><body>\n<p>Hello Foo</p>\n</body></html>"); assertThat(response.getContentAsString()).isEqualTo("<html><body>\n<p>Hello Foo</p>\n</body></html>");
} }
@Ignore
@Test @Test
public void renderTemplateWithoutRenderFunction() throws Exception { public void renderTemplateWithoutRenderFunction() throws Exception {
Map<String, Object> model = new HashMap<>(); Map<String, Object> model = new HashMap<>();
......
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
...@@ -337,39 +337,49 @@ mockMvc.get("/person/{name}", "Lee") { ...@@ -337,39 +337,49 @@ mockMvc.get("/person/{name}", "Lee") {
=== Kotlin Script Templates === Kotlin Script Templates
As of version 4.3, Spring Framework provides a Spring Framework provides a
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`] https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/script/ScriptTemplateView.html[`ScriptTemplateView`]
to render templates by using script engines. It supports which supports https://www.jcp.org/en/jsr/detail?id=223[JSR-223] to render templates by using script engines.
https://www.jcp.org/en/jsr/detail?id=223[JSR-223].
Spring Framework 5 goes even further by extending this feature to WebFlux and supporting
https://jira.spring.io/browse/SPR-15064[i18n and nested templates].
Kotlin provides similar support and allows the rendering of Kotlin-based templates. See By leveraging `kotlin-script-runtime` and `scripting-jsr223-embeddable` dependencies, it
https://github.com/spring-projects/spring-framework/commit/badde3a479a53e1dd0777dd1bd5b55cb1021cf9e[this commit] for details. is possible to use such feature to render Kotlin-based templates with
https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or Kotlin multiline interpolated `String`.
This enables some interesting use cases - such as writing type-safe templates by using `build.gradle.kts`
https://github.com/Kotlin/kotlinx.html[kotlinx.html] DSL or by a using Kotlin multiline `String` with interpolation. [source,kotlin,indent=0]
----
dependencies {
compile("org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}")
runtime("org.jetbrains.kotlin:kotlin-scripting-jsr223-embeddable:${kotlinVersion}")
}
----
This can let you write Kotlin templates with full autocompletion and Configuration is usually done with `ScriptTemplateConfigurer` and `ScriptTemplateViewResolver`
refactoring support in a supported IDE, as the following example shows: beans.
`KotlinScriptConfiguration.kt`
[source,kotlin,indent=0] [source,kotlin,indent=0]
---- ----
import io.spring.demo.* @Configuration
class KotlinScriptConfiguration {
@Bean
fun kotlinScriptConfigurer() = ScriptTemplateConfigurer().apply {
engineName = "kotlin"
setScripts("scripts/render.kts")
renderFunction = "render"
isSharedEngine = false
}
""" @Bean
${include("header")} fun kotlinScriptViewResolver() = ScriptTemplateViewResolver().apply {
<h1>${i18n("title")}</h1> setPrefix("templates/")
<ul> setSuffix(".kts")
${users.joinToLine{ "<li>${i18n("user")} ${it.firstname} ${it.lastname}</li>" }} }
</ul> }
${include("footer")}
"""
---- ----
WARNING: Kotlin Script Templates support is experimental and not compatible yet with Spring Boot fatjar mechanism, see related
https://youtrack.jetbrains.com/issue/KT-21443[KT-21443] and https://youtrack.jetbrains.com/issue/KT-27956[KT-27956]
issues.
See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example See the https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example
project for more details. project for more details.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册