Exemple de modèle Spring MVC + Moustache JS
Dans ce didacticiel, nous allons vous montrer un exemple d'application Web Spring MVC +Mustache JS template.
Technologies utilisées:
-
Spring 4.2.4.RELEASE
-
mustache.js
-
JDK 1.8.0_66
-
Jackson 2.7
-
Eclipse 4.3
-
Tomcat 8
-
Maven 3
-
Bootstrap 3
Note
Cette solution fonctionne toujours, mais recommande cette solution simple deSpring Boot + JMustache.
Au printemps, nous pouvons utiliserScriptTemplateConfigurer
pour intégrer la plupart des bibliothèques de modèles JS, par exemple Moustache, Handlebars ou React. Reportez-vous à cette documentation officielle deSpring script template.
P.S ScriptTemplateConfigurer
has been supported since Spring 4.2
Note
Cet exemple exécutera «Moustache JS» côté serveur, en utilisant le moteur Javascript Nashorn Java 8 intégré. Un exemple deisomorphic javascript.
1. Structure du projet
Une structure de dossiers Maven standard.
2. pom.xml
Un fichier Mavenpom.xml
pour déclarer les dépendances et quelques plugins utiles.
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} 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. Intégrer Spring + Moustache JS
Pour intégrer le modèle de script Moustache en tant que modèle de vue Spring, configurez à la foisScriptTemplateConfigurer
etViewResolver
. Voir le commentaire pour s'expliquer.
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. Contrôleur de printemps + modèle de 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»
Lorsqu'une vue est renvoyée, Spring exécutera cette fonctionrender(template, model, url)
. Mais, tous les objets ou types de données Java ne sont pas pris en charge en Javascript, la conversion est nécessaire, en particulier lesList<Object>
.
Sommaire :
-
Pour le type de données primitif, aucune conversion n'est nécessaire.
-
Pour
java.lang.Iterable
, convertissez-le avecJava.from()
. -
Pour
List<User>
, convertissez-le en chaîne au format JSON avecJackson
et convertissez-le en objet JS viaJSON.parse
. Cette astuce devrait fonctionner dans n'importe quelle conversion JavaScript d'objet Java.
/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. Classes diverses
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. Comment exécuter ce projet?
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/
Télécharger le code source
Télécharger -spring-mvc-mustache.zip (127 KB)
Lien Github -spring-mvc-mustache-js-template.git