В этом руководстве мы покажем вам пример веб-приложения Spring MVC +Mustache JS template.
Используемые технологии:
Весна 4.2.4. ВЫПУСК
mustache.js
JDK 1.8.0_66
Джексон 2,7
Затмение 4.3
Tomcat 8
Maven 3
Bootstrap 3
Note Это решение все еще работает, но рекомендуется это простое решениеSpring Boot + JMustache.
В Spring мы можем использоватьScriptTemplateConfigurer для интеграции большей части библиотеки шаблонов JS, например, Mustache, Handlebars или React. Обратитесь к этой официальной документацииSpring script template.
P.S ScriptTemplateConfigurer has been supported since Spring 4.2
Note В этом примере будет запущен «Mustache JS» на стороне сервера с использованием встроенного механизма Java 8 Nashorn Javascript. Примерisomorphic javascript.
1. Структура проекта
Стандартная структура папок Maven.
2. pom.xml
Файл Mavenpom.xml для объявления зависимостей и некоторых полезных плагинов.
Чтобы интегрировать шаблон сценария 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 + Усы Шаблон
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> преобразуйте его в строку в формате JSON с помощьюJackson и преобразуйте ее в объект JS черезJSON.parse. Этот прием должен работать при любом преобразовании JavaScript в 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. Разные Классы
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
}