Desidero eseguire un JavaScript all'interno di un servlet. È possibile riutilizzare lo stesso motore di scripting su tutte le chiamate di servlet? Le istanze servlet sono condivise da più thread. Ciò richiede la creazione di un nuovo motore di scripting per richiesta? Sarebbe una penalità di prestazioni inaccettabile. Ad esempio, è il seguente codice salvato?Riutilizzare Nashorn ScriptEngine in Servlet
public class MyServlet extends HttpServlet {
private ScriptEngineManager factory;
private ScriptEngine engine;
@Override
public void init() throws ServletException {
factory = new ScriptEngineManager();
engine = factory.getEngineByName("nashorn");
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
try (PrintWriter writer = res.getWriter()) {
ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put("writer", writer);
Object value = engine.eval("writer.print('Hello, World!');", engineScope);
writer.close();
} catch (IOException | ScriptException ex) {
Logger.getLogger(AsyncServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Se questo non è sicuro, quale sarebbe il modo migliore per evitare di creare un motore per ogni richiesta? Usando un pool di motori?
Edit: E 'possibile riutilizzare uno e lo stesso motore e la stessa cosa JavaScriptObject, che si traduce come la valutazione di un JS-funzione per tutte le richieste servlet, se la funzione non cambia condiviso oggetto ma usa solo gli argomenti dati con la chiamata? Guarda il seguente adattamento dell'esempio precedente:
public class MyServlet extends HttpServlet {
private ScriptEngineManager factory;
private ScriptEngine engine;
private ScriptObjectMirror script;
@Override
public void init() throws ServletException {
try {
factory = new ScriptEngineManager();
engine = factory.getEngineByName("nashorn");
script = (ScriptObjectMirror)engine.eval("function(writer) {writer.print('Hello, World!');}");
} catch (ScriptException ex) {
Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
try (PrintWriter writer = res.getWriter()) {
script.call(null, writer);
writer.close();
} catch (IOException ex) {
Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
È sicuro?
grazie! questo risponde alla mia domanda. e grazie per il suggerimento di utilizzare i locali dei thread. – Gregor
Si prega di consultare: http://stackoverflow.com/questions/30140103/should-i-use-a-separate-scriptengine-and-compiledscript-instances-per-each-threa – igr
Penso che dovresti passare 'newContext' a' eval' invece di 'engineScope' – gamliela