我想在Servlet中执行JavaScript。是否可以在所有servlet调用中重用相同的脚本引擎?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);
}
}
}
如果这样做不安全,那么避免每个请求创建引擎的最佳方法是什么?使用引擎池?
编辑:
是否可以对所有Servlet请求重用一个同一个引擎和一个同一个JavaScriptObject,作为对JS函数的求值,如果该函数不更改任何共享对象而仅使用给定的参数跟电话吗?查看上面示例的以下适应:
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);
}
}
这样安全吗?
在javax.script.ScriptEngineFactory
里面有一种方法getParameter(String key)
。
使用特殊键,THREADING
您可以获得该特定引擎工厂的线程信息。
这个小程序为每个注册的引擎工厂打印出此信息:
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
public class ScriptEngineTest {
public static void main(String[] args) {
final ScriptEngineManager mgr = new ScriptEngineManager();
for(ScriptEngineFactory fac: mgr.getEngineFactories()) {
System.out.println(String.format("%s (%s), %s (%s), %s", fac.getEngineName(),
fac.getEngineVersion(), fac.getLanguageName(),
fac.getLanguageVersion(), fac.getParameter("THREADING")));
}
}
}
对于Java 7,它是:
Mozilla Rhino (1.7 release 3 PRERELEASE), ECMAScript (1.8), MULTITHREADED
对于Java 8:
Oracle Nashorn (1.8.0_25), ECMAScript (ECMA - 262 Edition 5.1), null
null
表示引擎实现不是线程安全的。
在您的Servlet中,您可以使用ThreadLocal
来为每个线程保留一个单独的引擎,从而允许将引擎重新用于同一线程所服务的后续请求。
public class MyServlet extends HttpServlet {
private ThreadLocal<ScriptEngine> engineHolder;
@Override
public void init() throws ServletException {
engineHolder = new ThreadLocal<ScriptEngine>() {
@Override
protected ScriptEngine initialValue() {
return new ScriptEngineManager().getEngineByName("nashorn");
}
};
}
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
try (PrintWriter writer = res.getWriter()) {
ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(engineHolder.get().createBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put("writer", writer);
Object value = engineHolder.get().eval("writer.print('Hello, World!');", engineScope);
writer.close();
} catch (IOException | ScriptException ex) {
Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
我想在servlet中执行JavaScript。是否可以在所有servlet调用中重用相同的脚本引擎?Servlet实例由多个线程共享。这是否需要为每个请求创建一个新的脚本引擎?这将是一个不可接受的表现惩罚。例如,下面的代码是否保存? } 如果这是不安全的,那么避免为每个请求创建引擎的最佳方法是什么?使用一组引擎? 编辑:是否可以对所有servlet请求重用一个相同的引擎和一个相同的JavaScr
xml文件位于我的项目的中。我正在使用Eclipse并运行Tomcat(它不是通过Eclipse安装的,我更希望它是一个单独的安装)。 当表单页面提交给servlet时,它就不起作用了。我每次都得到一个404错误。我遇到这个问题有一段时间了。谁来帮帮我。
作为基础了解,在web应用程序范畴内使用 FreeMarker 和其它并没有什么不同; FreeMarker将它的输出写入传递给 Template.process 方法的 Writer 对象,它不关心 Writer 将输出写入控制台,文件或是 HttpServletResponse 的输出流。 FreeMarker 并不知道什么是servlet和web;它仅仅是使用模板文件来合并Java对象, 之
我有2个问题 1)我有一个login.jsp页和索引页。一旦我验证了用户(在servlet ie中),用户将被重定向到index.jsp页面。我用servlet的这条线重定向它 这个过程运行良好。但是当我刷新页面时,我会被重定向回登录页面。另外,我注意到在index.jsp页面上,我得到的名字而不是index.jsp,即我的servlet名称得到displayed.for这样的例子得到代替显示 2
我开始在eclipse中使用servlet开发java web应用程序,并在本地主机上用tomcat服务器测试它。我已经在tomcat中部署了应用程序,但是当我尝试在浏览器中加载目标url时,我得到了以下堆栈跟踪: ImageServlet类非常清楚地位于我的eclipse工作区的myproject/src/test文件夹中,其中myproject是eclipse项目的名称,test是包。 web
问题内容: 我正在尝试找到一种方法,可将请求从过滤器重定向到登录页面,但我不知道如何从servlet重定向。我搜索了,但发现的是方法。我在过滤器的响应对象上找不到此方法。是什么原因 我该如何解决? 问题答案: 在Filter中,响应是而不是。因此将强制转换为。 如果使用上下文路径: 也不要忘记在最后打电话。