Spring MVC + Moustache JSテンプレートの例

このチュートリアルでは、Spring MVC +Mustache JS templateのWebアプリケーションの例を示します。
使用される技術:
-
Spring 4.2.4.RELEASE
-
mustache.js
-
JDK 1.8.0_66
-
ジャクソン2.7
-
Eclipse 4.3
-
Tomcat 8
-
メーベン3
-
ブートストラップ3
Note
このソリューションは引き続き機能しますが、この単純なSpring Boot + JMustacheソリューションをお勧めします。
Springでは、ScriptTemplateConfigurerを使用して、Justache、Handlebars、ReactなどのほとんどのJSテンプレートライブラリを統合できます。 この公式のSpring script templateドキュメントを参照してください。
P.S ScriptTemplateConfigurer has been supported since Spring 4.2
Note
この例では、組み込みのJava 8 Nashorn Javascriptエンジンを使用して、サーバー側で「MustacheJS」を実行します。 isomorphic javascriptの例。
1. プロジェクト構造
標準のMavenフォルダー構造。

2. pom.xml
依存関係といくつかの便利なプラグインを宣言するためのMavenpom.xmlファイル。
pom.xml
4.0.0 com.example spring-mvc-mustache war 1.0-SNAPSHOT spring mvc mustache 1.8 4.2.4.RELEASE 3.1.0 1.1.3 1.7.12 2.7.0 org.springframework spring-webmvc ${spring.version} commons-logging commons-logging org.slf4j jcl-over-slf4j ${jcl.slf4j.version} ch.qos.logback logback-classic ${logback.version} javax.servlet javax.servlet-api ${servletapi.version} provided com.fasterxml.jackson.core jackson-databind ${jackson.version} org.apache.maven.plugins maven-compiler-plugin 3.3 ${jdk.version} ${jdk.version} org.eclipse.jetty jetty-maven-plugin 9.2.11.v20150529 10 /spring org.apache.maven.plugins maven-eclipse-plugin 2.9 true true 2.0 spring org.apache.maven.plugins maven-war-plugin 2.6 false
3. Spring + Moustache JSを統合する
MustacheスクリプトテンプレートをSpringビューテンプレートとして統合するには、ScriptTemplateConfigurerとViewResolverの両方を構成します。 自明のコメントを参照してください。
SpringWebConfig.java
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.script.ScriptTemplateConfigurer;
import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.example.web.controller" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
@Bean
public ScriptTemplateConfigurer configurer() {
ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();
//1. Nashorn jdk8 script engine.
configurer.setEngineName("nashorn");
//2. Add mustache.min.js and custom render.js to Nashorn
configurer.setScripts("/static/js/mustache.min.js", "/static/js/render.js");
//3. Ask Nashorn to run this function "render()"
configurer.setRenderFunction("render");
return configurer;
}
//Define where is Mustache template, in classpath level.
// If view "hello" is returned, Mustache temple will be '/static/templates/hello.html'
@Bean
public ViewResolver viewResolver() {
ScriptTemplateViewResolver viewResolver = new ScriptTemplateViewResolver();
viewResolver.setPrefix("/static/templates/");
viewResolver.setSuffix(".html");
return viewResolver;
}
//add static resources like js or css
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
4. Spring Controller + Moustacheテンプレート
4.1 A Spring controller to pass data to the Mustache template.
HelloController.java
package com.example.web.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.example.web.model.User;
@Controller
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
private static final ObjectMapper om = new ObjectMapper();
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView printWelcome(HttpServletRequest request) {
ModelAndView result = new ModelAndView();
result.addObject("resources", request.getContextPath() + "/resources");
result.addObject("logo", "example.com");
result.addObject("title", "Spring MVC + Mustache template");
result.addObject("jumbo-title", "Spring MVC + Mustache template");
result.addObject("jumbo-desc", "Maven + Spring MVC + Mustache JS, ScriptTemplate example.");
//1. Test data type
result.addObject("id", 100);
result.addObject("username", "example");
//2. Test List
result.addObject("scriptTemplates", getScriptTemplate());
//3. Test Object
result.addObject("user", new User("[email protected]", 0));
//4. Test List
4.2 A Mustache template file to display the data from the above Spring controller.
/static/templates/hello.html
{{title}}
{{jumbo-title}}
{{jumbo-desc}}
1. Data Types
{{#id}}
Hello {{username}}, id : {{.}}
{{/id}}
2. List
{{scriptTemplates}}
{{#scriptTemplates}}
- {{.}}
{{/scriptTemplates}}
3. User Object
{{user}}
{{#user}}
- email- {{user.email}}
- loginFailed- {{user.loginFailed}}
{{/user}}
4. List of User Objects (JSON)
{{user_json}}
{{#users_json}}
- email- {{email}}
- loginFailed- {{loginFailed}}
{{/users_json}}
5. List of User Objects (RAW)
No idea how to loop it...
{{users}}
{{#users}}
- email- {{email}}
- loginFailed- {{loginFailed}}
{{/users}}
5. Javascript「render.js」
ビューが返されると、Springはこの関数render(template, model, url)を実行します。 ただし、すべてのJavaオブジェクトまたはデータ型がJavascriptでサポートされているわけではないため、変換、特にList<Object>が必要です。
要約:
-
プリミティブデータ型の場合、変換の必要はありません。
-
java.lang.Iterableの場合は、Java.from()で変換します。 -
List<User>の場合は、Jacksonを使用してJSON形式の文字列に変換し、JSON.parseを介してJSオブジェクトに変換します。 このトリックは、JavaオブジェクトのJavaScript変換で機能するはずです。
/static/js/render.js
/**
* Bindings to use mustache.js with Nashorn.
*/
/**
* String templates: the Mustache template content. e.g hello.html
* Map model: the model in controller
* String url: the templates url (since 4.2.2)
*/
function render(template, model, url) {
return Mustache.render(template, toJsonObject(model));
}
// Some Java objects may not support in JS directly, need conversion.
function toJsonObject(model) {
var o = {};
for (var k in model) {
//Convert Object String to Javascript JSON
if (k.indexOf("_json") > -1) {
o[k] = JSON.parse(model[k]);
continue;
}
// Convert Iterable like List to real JSON array
if (model[k] instanceof Java.type("java.lang.Iterable")) {
o[k] = Java.from(model[k]);
}
else {
o[k] = model[k];
}
}
return o;
}
6. その他のクラス
6.1 Create a WebInitializer class to create a no web.xml web application.
MyWebInitializer
package com.example.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.example.config.SpringWebConfig;
public class MyWebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getServletConfigClasses() {
return new Class[] { SpringWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class>[] getRootConfigClasses() {
return null;
}
}
6.2 User Object.
User.java
package com.example.web.model;
public class User {
String email;
int loginFailed;
public User(String email, int loginFailed) {
this.email = email;
this.loginFailed = loginFailed;
}
//setters and getters
}
8. このプロジェクトを実行するには?
8.1 Clone the source code from Github.
$ git clone https://github.com/example/spring-mvc-mustache-js-template
8.2 Run the embedded Jetty container.
$ mvn jetty:run
8.3 Visit URL : http://localhost:8080/spring/

