私はSpringに比較的慣れていないので、あまり明白ではないことがあります。つまり、コントローラーがシングルトンであるという事実。これは良いアプローチであることに同意しますが、他のフレームワークで実装していたものを実装することはできません。
全体で AJAX リクエストを使用する Web アプリケーションを構築しています。BaseController
親としてのコントローラー階層があり、他のすべてのコントローラーはそれを拡張します。
クライアントに応答を返す必要があるコントローラー アクションは、@ResponseBody
アノテーションで注釈が付けられ、シリアル化された JSON 文字列をクライアントに返します。
createJSONResponse()
このシリアル化を実行するメソッドは に実装されてBaseController
おり、ここでの主なアイデアは、子コントローラーの各アクションがMap<String, Object> responseMap
クライアント データに必要なマップを設定し、このマップに でアクセスしてBaseController
シリアル化するというものです。
すべてのアクションで の新しいインスタンスを作成したくresponseMap
ないし、 のパラメータとして毎回渡したくありませんcreateJSONResponse()
。
プロパティとして宣言することで、他のフレームワークでこれを達成しresponseMap
ました。BaseController
protected
responseMap
すべてのコントローラーがシングルトンであり、リクエストごとに新しいインスタンスを作成できないため、Spring でこれを行うことはできません。
BaseController
リクエストをスコープにするのが良い考えかどうかはわかりません。
request スコープ Bean としてヘルパー クラスを作成し、このヘルパーで responseMap を宣言しました。次に、この Bean を のように注入し@Autowired
ましたBaseController
。createJSONResponse()
このヘルパーのメソッドも移動しました。次に、コントローラーから、このマップを as として入力しhelper.responseMap.add(<somedata>)
、 を呼び出しますhelper.createResponseMap()
。
この場合、 でresponseMap
空になりcreateResponseMap()
、コントローラ アクションで設定されたデータは含まれません。スレッドセーフでresponseMAp
はなく、非同期リクエストごとにスレッドからスレッドに移動しています。
必要な機能を実現する方法はありますか?
回避策 による解決: すべてのリクエストの前に responseMap をインスタンス化し、リクエスト インターセプターの HttpServletRequest オブジェクトに追加することで、問題を解決しました。次に、createJSONResponse() メソッドと responseMap の人口メソッドは、HttpServletRequest から responseMap を取得する getRequestMap() メソッドを参照します。
PS それでも、より良い解決策を知って喜んでいます。