40

Spring MVC を使用して JSON POST リクエストを処理しています。カバーの下では、Jackson JSON プロセッサ上に構築され、mvc:annotation-driven を使用するときに有効になる MappingJacksonHttpMessageConverter を使用しています。

私のサービスの 1 つは、アクションのリストを受け取ります。

@RequestMapping(value="/executeActions", method=RequestMethod.POST)
    public @ResponseBody String executeActions(@RequestBody List<ActionImpl> actions) {
        logger.info("executeActions");
        return "ACK";
    }

Jackson が requestBody を java.util.LinkedHashMap アイテムのリストにマップすることを発見しました (単純なデータ バインディング)。代わりに、型指定されたオブジェクトのリスト (この場合は「ActionImpl」) にリクエストをバインドしたいと考えています。

Jackson の ObjectMapper を直接使用すると、これは簡単に実行できます。

List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { }); 

しかし、Spring MVC と MappingJacksonHttpMessageConverter を使用する場合、これを達成するための最良の方法は何だろうと思っていました。ヒントはありますか?

ありがとう

4

5 に答える 5

43

コレクションの代わりに @RequestBody として配列を使用することで、型消去の問題を回避することもできることがわかりました。たとえば、次のように動作します。

public @ResponseBody String executeActions(@RequestBody ActionImpl[] actions) { //... }
于 2012-05-10T00:37:56.170 に答える
28

問題は型の消去が原因であると思われます。つまり、ジェネリックパラメーターの型を渡す代わりに、actions.getClass() のみが渡される可能性があります。これにより、List< ?> と同等の型が得られます。

これが当てはまる場合、1 つの可能性は、次のような中間サブクラスを使用することです。

public class ActionImplList extends ArrayList<ActionImpl> { }

クラスのみが渡された場合でも、これにより型情報が保持されるためです。それで:

public @ResponseBody String executeActions(@RequestBody ActionImplList actions)

トリックを行うでしょう。最適ではありませんが、動作するはずです。

Spring MVC の知識が豊富な人が、パラメーターの型が渡されない理由 (おそらくバグでしょうか?) を明らかにしてくれることを願っていますが、少なくとも回避策はあります。

于 2010-12-19T18:59:54.017 に答える
9

参考までに、この機能は Spring 3.2 で利用可能になります ( https://jira.springsource.org/browse/SPR-9570を参照) 。

現在の M2 でテストしたところ、すぐに使えるチャームのように動作します (パラメーター化された型を提供するために追加の注釈を提供する必要はありません。新しい MessageConverter によって自動的に解決されます)。

于 2012-09-26T09:12:10.393 に答える
2

この質問はすでに古いですが、とにかく少し貢献できると思います。

StaxMan が指摘したように、これは型消去によるものです。メソッド定義からのリフレクションを介してジェネリック引数を取得できるため、それ間違いなく可能です。ただし、問題はHttpMessageConverterの APIです。

T read(Class<? extends T> clazz, HttpInputMessage inputMessage);

ここでは、List.class のみがメソッドに渡されます。したがって、ご覧のとおり、メソッド パラメーターの型を見て実際の型を計算する HttpMessageConverter を実装することは不可能です。

それでも、独自の回避策をコーディングすることは可能です - HttpMessageConverter を使用しないだけです。Spring MVC を使用すると、標準の解決メソッドの前に開始する独自のWebArgumentResolverを作成できます。たとえば、ObjectMapper を直接使用して値を解析する独自のカスタム アノテーション (@JsonRequestBody?) を使用できます。メソッドからパラメーターの型を指定できます。

final Type parameterType= method.getParameterTypes()[index];
List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
    @Override
    public Type getType() {
        return parameterType;
    }
});

TypeReference が使用されることを意図した方法ではないと思いますが、ObjectMapper はより適切な方法を提供していません。

于 2011-12-17T10:29:48.933 に答える
0

メソッドを次のように宣言しようとしましたか:

executeActions(@RequestBody TypeReference<List<ActionImpl>> actions)

私はそれを試したことはありませんが、あなたの質問に基づいて、私最初に試すことです。

于 2010-12-15T19:43:00.473 に答える