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}}{{/users_json}}
- email- {{email}}
- loginFailed- {{loginFailed}}
5. List of User Objects (RAW)
No idea how to loop it...
{{users}}{{#users}}{{/users}}
- email- {{email}}
- loginFailed- {{loginFailed}}
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/