3

以前のデザイン

次のように構築されたSpringコントローラーがありました。

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET)
public ModelAndView getFunfData(@PathVariable("datatype") String dataType,
        WebRequest request) throws HttpException {

また、HandlerInterceptorAdapter前処理と後処理 (返されたモデルをポリシーに従って変更する) を実行する もありました。後処理ハンドラのシグネチャは次のとおりです。

@Override
public void postHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

それは実際にうまくいきました。REST API は適切に構造化されていない JSON ペイロードを返しましたが、少なくともインターセプター (ポリシー適用ポイント) はモデルから匿名化 (ユーザーの個人データを削除) し、それを置き換えることができました。

ModelAndViewポイントは、古い設計では、出力に送信される前に応答を取得し、変更してインスタンスに再注入できたことです。簡潔にするためにコードを投稿する必要はありません。

新しいデザイン

ここで、応答構造の欠陥を克服するのに役立つ新しい設計を発見しました。

私が持っていたとき、それは次return new ModelAndView(jacksonView_instance, "data", dataToConvertToJson)のように構成されていました

{
    "data": {
        "myAttr1":"myVal1"
     }
}

これは、受信プログラムがペイロードを JSON に変換したい場合に悪いことです。だから私は見つけた

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET, produces = { "application/json" })
    public @ResponseBody
    Object[] getFunfData(@PathVariable("datatype") String dataType,
            WebRequest request) throws HttpException {

この単純化されたコードは、次のように応答を適切に構造化しました。

{
    "myAttr1":"myVal1"
}

それは REST 設計契約ではまったく問題ありませんが、

問題

これで、HandlerInterceptor はモデルを取得できなくなり、API から返されたオブジェクトを取得できなくなります (これは、モバイル デバイスに記録された機密データであっても、個人データを処理するFUNF関連の API です)。

したがって、レコードを匿名化する必要がある場合、以前のようにインターセプターでは実行できません

回避策

インターセプターを強制終了し、API でポリシーの適用を実行できることを認識していますが、これは優れた設計ではありません。これは、 で承認を実行しpreHandle、義務の適用を実行する PEPpostHandleが現在、自動的にインスタンス化された Spring オブジェクトであるためです。API 内のコードをコピーして貼り付けるのは、複数の API を処理する場合に悪い考えであり、中期的に PEP 実装を変更/拡張する可能性があります。

とにかく、文脈をよく説明した上で、ストレートな質問を定式化しましょう

質問は

コンテンツ ネゴシエーターによって処理されるオブジェクトを返す汎用 Spring MVC API が与えられた場合

@RequestMapping(value = "/path/{variable}", method = RequestMethod.GET)
public @ResponseBody Object api() {

外部クラスで返されたオブジェクトをインターセプトして変更を実行するにはどうすればよいですか? (たとえば、クライアントに返される新しいオブジェクト インスタンスに置き換えます)

4

1 に答える 1

2

これはSpring MVC では不可能のようです。デバッグ セッションでコードを見たところです。

を使用するModelAndViewと、Spring MVC は MaV を存続する変数に格納し、postHandleそれをレスポンス ボディに書き込みます。

代わりに、値を使用@ResponseBodyして返す場合、その値は呼び出しサイクルで直接処理され、a を使用しMessageConverterて応答に書き込まれます。

応答は一方向のネットワーク ストリームであるため、傍受するには遅すぎます。

ソリューションは、コントローラー メソッドに直接適用されるAOPインターセプターなど、ハンドラーとは異なるアプローチに基づく必要があります。

于 2013-02-05T11:28:08.620 に答える