3

春のプロジェクトで次のインターフェイス/オブジェクト階層を検討してください。

public interface MyInterface {
    //method defenitions
}

@Component
@Scope(SCOPE_PROTOTYPE)
public class MyClass implements MyInterface {
   //method implementations
}

MyClassリクエスト本文から読み取られるコントローラーメソッドで使用します。

@RequestMapping(method = POST, value = "/posturi", consumes = "application/json")
public void createEntity(@RequestBody MyClass myClass) {
    //handle request
}

jackson ライブラリは、json データを読み取り、それを Java オブジェクトに変換するために使用されます。

MyClassコントローラーメソッドのパラメーターの型を からに変更したいと思いますMyInterfacenewインターフェースをオペレーターでインスタンス化できないため、これは機能していないようです。しかし、次のように作成できます。

MyInterface instance = applicationContext.getBean(MyInterface.class);

この方法でスプリング/ジャクソンにオブジェクトをインスタンス化させることは可能ですか? コントローラーがどの実装が使用されているかを認識する必要がないように、これを行いたいと思います。

4

2 に答える 2

0

私はこれを解決しました。概念は非常に単純ですが、実装は少し難しい場合があります。私が理解しているように、http 要求から目的の型に変換できる@RequestBodyを提供する限り、任意の型に注釈を付けることができます。HttpMessageConverterしたがって、解決策は次のとおりです。

  1. 実装するHttpMessageConverter
  2. が使用されるように春を構成しますHttpMessageConverter

2番目の部分は少し難しいかもしれません。HttpMessageConverterこれは、Spring が文字列、整数、日付などの一般的な型を処理できる一連のデフォルトを追加し、これらが通常どおり機能し続けるようにするためです。もう 1 つの問題は、jackson がパス上にある場合、Spring が、MappingJackson2HttpMessageConverter具体的なオブジェクトやマップなどへの変換などの一般的な json 処理用の も追加することです。Spring はHttpMessageConverter、型に変換できると主張する最初に見つかったものを使用します。私のMappingJackson2HttpMessageConverterオブジェクトに対してそれができると主張していますが、それができないため、失敗し、リクエストは失敗します。これはバグと見なすことができます...

私が欲しかったチェーンは:

  1. スプリングのデフォルトHttpMessageConverters.
  2. 自分のHttpMessageConverter
  3. MappingJackson2HttpMessageConverter

これを達成するための2つの方法を見つけました。まず、これを xml で明示的に宣言できます。

<mvc:annotation-driven>
    <mvc:message-converters>
        <!-- All converters in specific order here -->
    </mvc:message-converters>
</mvc:annotation-driven>

これの欠点は、デフォルトのHttpMessageConverterチェーンが後のリリースで変更された場合、構成では変更されないことです。

それを行う別の方法は、プログラムで独自HttpMessageConverterMappingJackson2HttpMessageConverter.

@Configuration
public class MyConfiguration {

    @Autowired
    private RequestMappingHandlerAdapter adapter;

    @Autowired
    private MyHttpMessageConverter myHttpMessageConverter;

    @PostConstruct
    private void modify() {
        List<HttpMessageConverter<?>> messageConverters = adapter.getMessageConverters();
        int insertLocation = messageConverters.size() - 1;
        for (int i = 0; i < messageConverters.size(); i++) {
            Object messageConverter = messageConverters.get(i);
            if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
                insertLocation = i;
            }
        }
        messageConverters.add(insertLocation, myHttpMessageConverter);
    }
}

2 番目の選択肢は、今後のリリースで変更された場合でも、引き続き「既定の構成」を使用します。私はそれが少しハックであり、まったくエレガントではないと考えていますが、それが有効な解決策であると考える理由は、MappingJackson2HttpMessageConverter変換できない型に変換できるという主張に欠陥があるように見えるからです。またHttpMessageConverter、チェーンの特定の位置に a を明示的に追加することはできません。

今のところ、私は 2 番目のオプションを使用しますが、どのようにするかはあなた次第です...

于 2013-05-21T07:23:01.283 に答える