我正在使用 java servlet 开发一个 Web 应用程序,这是我的场景:
servlet1: Has the application's interface and main logic
servlet2: Suplies values to servlet1 on ajax request from servlet1
servlet1 总共可以请求 250 个值。但是在 servlet2 中计算这些值需要时间(因为它涉及向其他服务器发出 GET 请求以获取值)。因此根据请求计算这些值会使客户端等待很长时间。
那么有没有办法让 servlet2 在第一次调用 servlet1 时开始预先计算值(以便它可以根据请求快速发送值)?
关于如何实现这一点有任何帮助吗?
附注无法使用数据库或文件系统。
最佳答案
如果servlet2
需要预先计算的数据不依赖于servlet1
输入并且只需要计算一次,则要么在ServletContextListener.contextInitialized()
中急切地计算它或在 GenericServlet.init()
。但是,如果计算需要一些时间,您最好将其移动到某个后台线程,以避免应用程序启动时间过长(这些方法会阻止部署,直到完成)。
这是一个简单的例子:
public class Servlet2 extends HttpServlet {
private final ExecutorService threadPool = Executors.newSingleThreadExecutor();
private Future<String> calculationResult;
@Override
public void init() throws ServletException {
calculationResult = threadPool.submit(new PreComputingTask());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final String slowResponse = calculationResult.get();
//...
}
}
class PreComputingTask implements Callable<String> {
@Override
public String call() throws Exception {
//Call external systems, whatever...
return "slow response";
}
}
如您所见,当 servlet2 启动时,它会在单独的线程中启动预计算任务。然后在 doGet()
中检索结果,如果尚未完成,可能会等待它。
如果预计算依赖于servlet1
中的输入(例如调用外部系统时需要使用servlet1
的请求参数),则更具挑战性和有趣性.
我至少看到两个选择:
在
servlet1
中启动Future
任务,并在servlet2
中检索该 future(希望已经完成)。您需要以某种方式在 servlet 之间传递它,例如将其放入ServletContext
发送消息至jms来自
servlet1
的队列。消息监听器将处理请求,预先计算结果并将结果放入某个临时的、唯一的队列中。servlet2
随后可以从该队列接收消息(您必须以某种方式就某些命名方案达成一致),或者稍等一下。
关于java - 如何让 servlet 在访问其他 servlet 时预先计算值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11990064/