質問

Spring MVCを使用してJSONの投稿リクエストを処理しています。カバーの下で、Jackson JSONプロセッサに構築されたMappingJacksonHTTPMessageConverterを使用しており、MVC:Annotation-Drivenを使用すると有効になっています。

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

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

Jacksonは、java.util.linkedhashmapアイテムのリストにリクエストボディをマッピングすることがわかりました(単純なデータバインディング)。代わりに、リクエストを型付けされたオブジェクトのリスト(この場合は「ActionImpl」)にバインドしたいと思います。

JacksonのObjectMapperを直接使用する場合、これは簡単であることを知っています。

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

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

ありがとう

役に立ちましたか?

解決

問題は、型の消去、つまり汎用パラメータータイプを渡す代わりに、アクションのみを渡す代わりに、getClass()が渡されることによるものだと思います。そして、これにより、リスト<?>に相当するタイプが得られます。

これが真実であれば、次のような中間サブクラスを使用する可能性があります。

public class ActionImplList extends ArrayList<ActionImpl> { }

これは、クラスのみが渡された場合でも、タイプ情報を保持するためです。それで:

public @ResponseBody String executeActions(@RequestBody ActionImplList actions)

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

より多くのスプリングMVCの知識を持つ人が、パラメータータイプが渡されない理由に光を当てることができることを願っています(おそらくバグですか?)が、少なくとも回避策があります。

他のヒント

また、コレクションの代わりに@RequestBodyとして配列を使用することで、タイプ消去の問題を回避できることがわかりました。たとえば、以下は機能します。

public @ResponseBody String executeActions(@RequestBody ActionImpl[] actions) { //... }

あなたの情報については、この機能は春3.2で利用可能になります(参照 https://jira.springsource.org/browse/spr-9570)

私はそれを現在のM2でテストしたばかりで、それは箱から出して魅力のように機能します(パラメーター化されたタイプを提供するために追加のアノテーションを提供する必要はありません、それは新しいMessageConverterによって自動的に解決されます)

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

Staxmanが指摘したように、これはタイプの消去によるものです。それは間違いなく したほうがいい あなたが可能だからです できる メソッド定義からの反射を介して一般的な引数を取得します。ただし、問題はAPIです httpmessageconverter:

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はより適切な方法を提供しません。

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top