0

我正在使用 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 时开始预先计算值(这样它就可以根据请求快速发送值)?
关于如何实施的任何帮助?

无法使用 PS 数据库或文件系统。

4

3 回答 3

1

我将尝试对 servlet1 进行过滤,该过滤器启动异步操作以计算您需要的值,然后在 servlet2 的逻辑中检索它们。

所以基本上你拦截了 servlet1 请求(使用过滤器),该请求在第一次调用 servlet1 时触发,并且在过滤器中开始预先计算值,并且它们 servlet2 从 servlet1 检索请求的值。

于 2012-08-16T15:15:13.890 回答
1

servlet2 是否需要来自 servlet1 的一些值才能开始计算这些值?如果没有,您可以将计算代码移到与两个 servlet 分开的类中。ServletContextListener 可以在 ServletContext 初始化时触发,在任何请求进入之前,这可以开始计算。完成后,它可以将这些结果存储在 ServletContext 中

然后 Servlet2 可以检查这些结果是否已计算(是否在 ServletContext 中?),如果是,则使用它。否则它可以计算单个值。理想情况下,您的单独班级将知道如何计算所有值(用于预计算)或单个值(用于尚未完成完整列表时)。

于 2012-08-16T15:21:36.710 回答
1

如果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

我看到至少两个选项:

  • 开始Future任务servlet1并检索未来(希望已经完成)servlet2。您需要以某种方式在 servlet 之间传递它,例如将它放在ServletContext

  • 队列发送消息servlet1。消息侦听器将处理请求,预先计算结果并将结果放入某个临时的、唯一的队列中。servlet2然后可以稍后从该队列接收消息(您必须以某种方式就某种命名方案达成一致),或者稍等一下。

于 2012-08-17T17:29:26.167 回答