0

私はJavaサーブレットを使用してWebアプリケーションに取り組んでおり、これが私のシナリオです:

servlet1: Has the application's interface and main logic
servlet2: Suplies values to servlet1 on ajax request from servlet1

servlet1 が要求できる値は全部で 250 あります。ただし、servlet2 でこれらの値を計算するには時間がかかります (値を取得するために他のサーバーに GET 要求を行う必要があるため)。そのため、要求に応じてこれらの値を計算すると、クライアントは長時間待機します。

サーブレット1が最初に呼び出されたときに値の事前計算を開始するようにサーブレット2を作成する方法はありますか(リクエストに応じて値をすばやく送信できます)?
これを実装する方法について何か助けはありますか?

PS データベースまたはファイルシステムは使用できません。

4

3 に答える 3

1

事前計算が必要なデータが入力にservlet2依存せず、一度だけ計算する必要がある場合は、 inまたは inservlet1で熱心に計算します。ただし、計算に時間がかかる場合は、バックグラウンド スレッドに移動して、アプリケーションの起動時間が長くならないようにすることをお勧めします (これらのメソッドは、完了するまで展開をブロックします)。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)、それははるかに困難で興味深いものです。

少なくとも 2 つのオプションがあります。

  • Futureでタスクを開始し、servlet1その未来 (できれば既に完了している) を で取得しますservlet2。たとえば、サーブレット間で何らかの方法で渡す必要があります。ServletContext

  • キューにメッセージを送信しますservlet1。メッセージリスナーはリクエストを処理し、結果を事前に計算して、結果を一時的な一意のキューに入れます。servlet2その後、後でそのキューからメッセージを受信するか (名前付けスキームに同意する必要があります)、少し待つことができます。

于 2012-08-17T17:29:26.167 に答える
1

値の計算を開始するために、servlet2 は servlet1 からのいくつかの値を必要としますか? そうでない場合は、計算コードを 2 つのサーブレットとは別のクラスに移動できます。ServletContextListener は、ServletContext が初期化されたときに、リクエストが来る前に起動することができ、これにより計算が開始されます。完了すると、これらの結果を ServletContext に格納できます。

Servlet2 は、これらの結果が計算されているかどうか (ServletContext にあるかどうか) を確認し、計算されている場合はそれを使用します。それ以外の場合は、個別の値を計算できます。理想的には、個別のクラスがすべての値を計算する方法 (事前計算の場合) または個別の値を計算する方法 (完全なリストがまだ完成していない場合) を知っている必要があります。

于 2012-08-16T15:21:36.710 に答える
1

非同期操作を開始して必要な値を計算し、それらを servlet2 のロジックで取得する servlet1 へのフィルターを試します。

したがって、基本的には、servlet1 が最初に呼び出されたときにトリガーされる servlet1 要求を (フィルターを使用して) インターセプトし、フィルター内で値の事前計算を開始し、それらの servlet2 は要求に応じて servlet1 から値を取得します。

于 2012-08-16T15:15:13.890 に答える