最新かつ最高の Spring 3.2.3、Tomcat 7.0.42、Servlet 3.0 コンテナー、Java 7 を使用します。応答のために JSONP を実行する必要があるため、次のように Servlet Filter を実行して実装します。
しかし、現在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:
いくつかの異なるリソースを読んだ結果、いくつかのことがわかりました。
- From: Spring Aync プレビュー ブログ
サーブレット フィルタ
*すべての Spring Framework サーブレット フィルター実装は、非同期リクエスト処理で動作するように必要に応じて変更されています。他のフィルターに関しては、一部は機能します (通常、前処理を行うものと、変更が必要なものがあります)。通常は、リクエストの最後で後処理を行うものです。このようなフィルターは、最初のサーブレット コンテナー スレッドが終了し、別のスレッドが処理を続行できるようになったときと、処理を完了するために非同期ディスパッチの一部として呼び出されたときを認識する必要があります。**
- Spring MVC Refから。docs、私は実際にRTFMしました:
DeferredResult を使用した非同期リクエスト処理の一連のイベントは、アプリケーションが何らかのスレッドから非同期の結果を生成することを除いて、原則として同じです: (1) コントローラは DeferredResult を返し、メモリ内のキューまたはリストに保存します。アクセスできます。(2) Spring MVC が非同期処理を開始します。(3) DispatcherServlet とすべての構成済みフィルターがリクエスト処理スレッドを終了しますが、レスポンスは開いたままです。(4) アプリケーションがスレッドから DeferredResult を設定し、Spring MVC がリクエストをディスパッチします。 (5) DispatcherServlet が再度呼び出され、非同期的に生成された結果で処理が再開されます。
したがって、基本的に、別のスレッドがフィルターを呼び出すことを知っていました/知っていました...それは私を悩ませていたものではありません..フィルターが応答を変更する必要があるかどうかを判断する方法でした...そしてあなたはできます' 0 バイトが正しい「答え」である可能性があるため、データのサイズを確認してください。
したがって、 DispatchType = ASYNC の場合にのみ書き込みます
これが長期的に正しいかどうかはよくわかりませんが、問題は解決しているようです。
他の提案/アイデアはありますか?