2017-06-29 6 views
1

RestTemplate経由でjson-Stringとして受け取った値を従来のAPIからデシリアライズするミドルウェアアプリケーションで作業しています(したがって、 "その"データモデルへの影響がないため、私のオブジェクトマッパーがこのapiを消費するためのいくつかのカスタム設定)、そしてそのアプリケーション自体はlegacydataに基づいて(部分的に豊富で合成された)安静なAPIをjsonとして提供します。1つのSpringBootアプリケーションで異なる構成のObjectMappersを使用する

は今、私のレガシー・マッピング・クラスのコンストラクタは、すべての瞬間に、このような共通の構造を共有している:私はするジャクソンを使用しているため

... 
    private ObjectMapper mapper; 

    public MyMapper() { 
     this.mapper = new ObjectMapper(); 
     this.mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); 
     this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    } 
    ... 

がlegacysystemからJSONをデシリアライズ。基本的に私はスプリングDIコンテナを使用してこの冗長性をリファクタリングしたいと思います。

は、だから私はそれがこのスレッドではいくつかの回答に記載されているように、単にObjectMapperを拡張して自分のObjectmapper @Componentを作成しようとしました: Configuring ObjectMapper in SpringからFromLegacyObjectMapperそれを呼び出すことができます - 代わりに、すべてのクラスで私のマッパーを初期化するので、私は1を作成し、使用されている

@Autowired 
private FromLegacyObjectMapper 

(または、単純化のために、コンストラクタインジェクション同等物)。 しかし、これには重大な副作用がありました。実際、フロントワイヤからviewModelを直列化解除するときに、実際に必要なスプリングブート標準のオブジェクトマッパーをautowiringが上書きするため、rootvalue-wrappingのために、私は自分のコントローラ内のビューモデルにclientjsonをdeserializeできませんでした。

は、私はそれを取得しようと、次のように実行している:

frontend <---> My Api using Standard ObjectMapper <--> viewModel created by consuming legacy-Api-json using FromLegacyObjectMapper 

をので、私は確かに私のmappingclassesのための基底クラスを使用して、ちょうどベースのコンストラクタに上記のコードを追加している何ができるか、およびすべてのを聞かせてMapperclassはこの基盤を拡張していますが、実際には、スプリング依存性注入コンテナを代わりに使用する方法を見つけることを望んでいました。私は今のアイデアがないので、誰もが私を助けてくれることを願っています!

編集:少し明快にするために、下記のMoritzの回答とコメントの中での議論をご覧ください。私は、@Qualifier注釈を使用できることをよく知っていますが、スプリングコントローラで使用される標準オブジェクトマッパーに@Qualifierを追加する方法があれば、これで問題は解決します。私は自分でいくつかの研究をしますが、他の答えは大歓迎です。

答えて

1

2つの異なるObjectMapperをSpringコンテナに追加しようとします。

@Bean 
@Qualifier("fromLegacy") 
public ObjectMapper fromLegacyObjectMapper() { 

    // create and customize your "from legacy" ObjectMapper here 

    return objectMapper; 
} 

@Bean 
@Qualifier("default") 
public ObjectMapper defaultObjectMapper() { 

    // create your default ObjectMapper here 

    return objectMapper; 
} 

は、その後、あなたがこのように従来のAPIを使用するクラスにObjectMapper「レガシーから」注入することができます:あなたは、あなたのApplicationクラスに、たとえば、このような何かを追加することができます(と仮定すると、それは@SpringBootApplicationで注釈を付け1です) :

public class SomeServiceUsingLegacyApi { 

    private final ObjectMapper objectMapper; 

    @Autowired 
    public SomeServiceUsingLegacyApi(@Qualifier("fromLegacy") ObjectMapper objectMapper) { 

     this.objectMapper = objectMapper; 
    } 

    // [...] 
} 

し、それに応じて他のAPIを使用して、他のクラス、中:

public class SomeServiceUsingOtherApi { 

    private final ObjectMapper objectMapper; 

    @Autowired 
    public SomeServiceUsingOtherApi(@Qualifier("default") ObjectMapper objectMapper) { 

    this.objectMapper = objectMapper; 
    } 

    // [...] 
} 
+0

が、私は私のCONTRに標準objectmapperを注入していないですこれは春の内部で行われています。だから私はここに予選を加えることに何の影響もないんですか?私はその中にいました。ここ数年間はNETの世界ですので、ごめんなさい。) – Dominik

+0

Spring Applicationコンテキストに 'ObjectMapper' Beanのような独自のBeanを追加することはできません。コンテキスト内で同じタイプの異なるBeanを使用している場合、 '@ Qualifier'アノテーションを使用して、どのBeanを使用するかをSpringに指示できます。私はあなたに明確にするための例を挙げたいが、今は十分な時間がない。また、Craig Wallsの "Spring in Action"でも良い例が見つかります。 – anothernode

+0

ああ、私は今、上記のコメントであなたの質問を本当に理解しており、私の例はそれに答えていません。私はそれについてもっと研究しなければならないでしょう... – anothernode

関連する問題