mirror of
https://github.com/Febbweiss/springboot-react-webpack.git
synced 2026-03-04 22:25:34 +00:00
Optim: more generic server side JS engine
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package com.opengroupe.cloud.saas.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class JavaScriptEngine {
|
||||
|
||||
private final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
|
||||
|
||||
public JavaScriptEngine polyfillToNashorn() {
|
||||
this.loadFromClassPath("static/js/nashorn-polyfill.js");
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaScriptEngine eval(String script) {
|
||||
try {
|
||||
this.scriptEngine.eval(script);
|
||||
} catch (ScriptException e) {
|
||||
throw new IllegalStateException("Failed to eval " + script + "!", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaScriptEngine loadFromClassPath(String file) {
|
||||
try {
|
||||
this.scriptEngine.eval(readFromClassPath(file));
|
||||
} catch (ScriptException e) {
|
||||
throw new IllegalStateException("Failed to loadFromClassPath " + file + "!", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object invokeFunction(String functionName, Object... args) {
|
||||
try {
|
||||
return ((Invocable) this.scriptEngine).invokeFunction(functionName, args);
|
||||
} catch (ScriptException | NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException("Failed to invoke " + functionName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T invokeFunction(String functionName, Function<Object, T> converter, Object... args) {
|
||||
return converter.apply(invokeFunction(functionName, args));
|
||||
}
|
||||
|
||||
private String readFromClassPath(String path) {
|
||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream(path)) {
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException(path + " is not found!");
|
||||
}
|
||||
return copyToString(in, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to read " + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String copyToString(InputStream in, Charset charset) throws IOException {
|
||||
StringBuilder out = new StringBuilder();
|
||||
try (InputStreamReader reader = new InputStreamReader(in, charset);) {
|
||||
char[] buffer = new char[4096];
|
||||
int bytesRead = -1;
|
||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
||||
out.append(buffer, 0, bytesRead);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.opengroupe.cloud.saas.web;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -12,7 +13,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.opengroupe.cloud.saas.domain.Comment;
|
||||
import com.opengroupe.cloud.saas.service.CommentService;
|
||||
import com.opengroupe.cloud.saas.util.React;
|
||||
import com.opengroupe.cloud.saas.util.JavaScriptEngine;
|
||||
|
||||
@Controller
|
||||
public class ViewController {
|
||||
@@ -20,14 +21,23 @@ public class ViewController {
|
||||
@Autowired
|
||||
private CommentService service;
|
||||
|
||||
@Bean
|
||||
JavaScriptEngine nashornEngine() {
|
||||
return new JavaScriptEngine().polyfillToNashorn()
|
||||
.loadFromClassPath("META-INF/resources/webjars/react/0.14.7/react.min.js")
|
||||
.loadFromClassPath("META-INF/resources/webjars/marked/0.3.2/marked.js")
|
||||
.loadFromClassPath("static/js/app.js")
|
||||
.loadFromClassPath("static/js/app.render.js");
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private React react = new React();
|
||||
ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
JavaScriptEngine nashorn;
|
||||
|
||||
@RequestMapping("/greeting")
|
||||
public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
|
||||
public String greeting(@RequestParam(value = "name", required = false, defaultValue = "World") String name,
|
||||
Model model) {
|
||||
model.addAttribute("name", name);
|
||||
return "greeting";
|
||||
}
|
||||
@@ -35,10 +45,10 @@ public class ViewController {
|
||||
@RequestMapping("/index")
|
||||
public String index(Model model) throws JsonProcessingException {
|
||||
List<Comment> comments = service.getAll();
|
||||
String commentBox = react.renderCommentBox(comments);
|
||||
String data = objectMapper.writeValueAsString(comments);
|
||||
model.addAttribute("markup", commentBox);
|
||||
model.addAttribute("data", data);
|
||||
String markup = nashorn.invokeFunction("renderServer", String::valueOf, comments);
|
||||
String data = objectMapper.writeValueAsString(comments);
|
||||
model.addAttribute("markup", markup);
|
||||
model.addAttribute("data", data);
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user