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.
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}}
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»
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.
PourList<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.
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
}