4

最新かつ最高の Spring 3.2.3、Tomcat 7.0.42、Servlet 3.0 コンテナー、Java 7 を使用します。応答のために JSONP を実行する必要があるため、次のように Servlet Filter を実行して実装します。

http://jpgmr.wordpress.com/2010/07/28/tutorial-implementing-a-servlet-filter-for-jsonp-callback-with-springs-delegatingfilterproxy/

しかし、現在web.xmlがなければ..Java Annotation Configを使用しています。

私たちの@Controllerでは、 を返しDeferredResult<String>ます。次に、@Serviceによって呼び出される@Controllerには、@Async注釈があります。@Async(AysncContext ルートではなく) ルートを選択した理由は、これが「ファイア アンド フォーゲット」タイプの非同期操作であるためです。ただし、操作が開始されたことを示す JSON をリクエスターに返す必要があります。

@RequestMapping(method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public DeferredResult<String> testing(@RequestParam(value="submit", required=true) String param)
{
            final DeferredResult<String> result = new DeferredResult<String>();
            service.doIt(param, result);

            return result;
}

そして私たちの@Service

@Async
public DeferredResult<String> doIt(String param2, DeferredResult<String> result)
{
    log.info("Calling Async doIt Method");
    result.setResult("{hello:there}");
}

行き詰まっています... Java Config でサーブレット フィルターの非同期サポートタグを追加する方法があるかどうかを調べようとしていますか? 私はこのプレゼンテーション (スライド 28) を見てそれを基にしています。

http://rstoyanchev.github.io/spring-mvc-32-update/#28

その他の情報:

@EnableAsync構成があり、AbstractAnnotationConfigDispatcherServletInitializer を使用してアプリケーションを定義していますが、非同期フィルターを使用するように指示する方法がわかりません (JsonpFilter を返すために を使用するだけですgetServletFilters())。

基本的に何が起こっているかというと、JSONP フィルターが何も「ラップ」していないということです...しかし、TaskExecutor スレッドで結果が設定された後、フィルターが 2 度目に呼び出されていることがわかります..しかし、その時点で応答は既に出ています...だから、フィルター「get Data」が 2 回表示されます。1 回目は@Controllerメソッドが終了したとき、2 回目は DeferredResult.setResult() が設定された直後です。

Filter クラスでもこれを試しました。

@WebFilter(urlPatterns = "/*", asyncSupported = true)

しかし、それは機能しませんでした(ログによると、2つの別々のフィルターを作成したように見えました..しかし、それについて間違っている可能性があります)。

必要に応じて Callable に切り替えることができます..それは大したことではありません。Spring が認識しているスレッドに関して、DeferredResult と Callable の間にいくつかの違いがあることがわかりました。

答えが web.xml を使用する必要があるという場合、web.xml ハイブリッドで Java Config を実行する本当に良い方法はありますか?

編集1:

いくつかの異なるリソースを読んだ結果、いくつかのことがわかりました。

  1. From: Spring Aync プレビュー ブログ

サーブレット フィルタ

*すべての Spring Framework サーブレット フィルター実装は、非同期リクエスト処理で動作するように必要に応じて変更されています。他のフィルターに関しては、一部は機能します (通常、前処理を行うものと、変更が必要なものがあります)。通常は、リクエストの最後で後処理を行うものです。このようなフィルターは、最初のサーブレット コンテナー スレッドが終了し、別のスレッドが処理を続行できるようになったときと、処理を完了するために非同期ディスパッチの一部として呼び出されたときを認識する必要があります。**

  1. Spring MVC Refから。docs、私は実際にRTFMしました:

DeferredResult を使用した非同期リクエスト処理の一連のイベントは、アプリケーションが何らかのスレッドから非同期の結果を生成することを除いて、原則として同じです: (1) コントローラは DeferredResult を返し、メモリ内のキューまたはリストに保存します。アクセスできます。(2) Spring MVC が非同期処理を開始します。(3) DispatcherServlet とすべての構成済みフィルターがリクエスト処理スレッドを終了しますが、レスポンスは開いたままです。(4) アプリケーションがスレッドから DeferredResult を設定し、Spring MVC がリクエストをディスパッチします。 (5) DispatcherServlet が再度呼び出され、非同期的に生成された結果で処理が再開されます。

したがって、基本的に、別のスレッドがフィルターを呼び出すことを知っていました/知っていました...それは私を悩ませていたものではありません..フィルターが応答を変更する必要があるかどうかを判断する方法でした...そしてあなたはできます' 0 バイトが正しい「答え」である可能性があるため、データのサイズを確認してください。

したがって、 DispatchType = ASYNC の場合にのみ書き込みます

これが長期的に正しいかどうかはよくわかりませんが、問題は解決しているようです。

他の提案/アイデアはありますか?

4

4 に答える 4

2

AbstractAnnotationConfigDispatcherServletInitializer を拡張している場合は、このメソッドをオーバーライドして非同期サポートを設定できるようです。

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    registration.setInitParameter("dispatchOptionsRequest", "true");
    registration.setAsyncSupported(true);
}
于 2014-05-02T18:14:30.080 に答える
2

コントローラーメソッドに @Async を追加することでこれを解決しました。私の推測では、それを行うことで、舞台裏のフィルターを処理することができます。

于 2015-01-02T04:12:42.310 に答える
2

以下のように、各サーブレット インスタンスに asyncSupport フラグを設定するだけです。

@Override
public void onStartup(final ServletContext servletContext)
        throws ServletException {
    final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.setServletContext(servletContext);
    root.scan("com.my.site");
    root.refresh();
    final Dynamic servlet = servletContext.addServlet("cf-validator",
            new DispatcherServlet(root));
    servlet.setLoadOnStartup(1);
    servlet.addMapping("/api/*");
    servlet.setAsyncSupported(true);
}
于 2014-08-21T14:08:37.917 に答える