ジャクソンや春ブーツでカスタムデシリアライザを提供する方法

Margul:

私は、次の3つのアプリケーションがあります。

プロジェクト1が成り立ちます

  • ビジネスロジック(春クラウド機能)
  • インタフェースIDemoEntity

プロジェクト2

  • AWS固有のハンドラ
  • 一の実施IDemoEntity DynamoDBの固有の注釈を含みます、
  • このプロジェクトは、春のブートに基づいています

プロジェクト3

  • 一の実施IDemoEntity CosmosDB注釈と、
  • Azureの固有のハンドラ

プロジェクト1のクラスは、次のようになります。

public interface IDemoEntity {
    String getName();
    void setName(String name);
}

@Component
public class StoreFunction implements Consumer<Message<IDemoEntity>> {

    @Override
    public void accept(Message<IDemoEntity> t) {

        System.out.println("Stored entity " + t.getPayload().getName());
        return;
    }
}

プロジェクト2について、IDemoEntityの実装は次のようになります。

@DynamoDBTable(tableName = "DemoEntity")
public class DynamoDemoEntity implements IDemoEntity {

    private String name;
    @Override
    @DynamoDBHashKey
    public String getName() {

        return name;
    }

    @Override
    public void setName(String name) {

        this.name = name;
    }    
}

プロジェクト3については、実施のIDemoEntityはのようになりDynamoDemoEntityが、CosmosDB注釈を含みます。

構造が複雑少し見えるかもしれませんが、考え方は以下の通りであります:

  1. (春のクラウド機能を活用)(プロジェクト1)ビジネスロジックとデータモデル1時間を実装
  2. 単なるラッパーの各プラットフォームのためのプロジェクト(私はプロジェクト2にAWSラムダから始まるんだけど、プロジェクト3アズールについても同様になります)だけでなく、プラットフォーム固有のものを実装(DB固有の注釈を必要とするエンティティの実装、など)
  3. 依存関係としてプロジェクト1で、プラットフォーム固有のプロジェクト(AWSラムダ用などのプロジェクト2)をコンパイルします

私はそれを試してみた、とセットアップは基本的に動作します。しかし、一つの大きな問題があります:

呼び出すときStoreFunctionを上記、ジャクソンは次の例外がスローされます。

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `de.margul.awstutorials.springcloudfunction.logic.IDemoEntity` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (String)"{"name": "Detlef"}"; line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at de.margul.awstutorials.springcloudfunction.aws.handler.RestSpringBootApiGatewayRequestHandler.deserializeBody(RestSpringBootApiGatewayRequestHandler.java:57)
    ... 3 more

ジャクソンは知らないので、それは実装にあれば、理にかなってIDemoEntity、それは受け取ったJSONをデシリアライズするものとします。

最も簡単な方法は、今置くことであろう@JsonDeserialize(as = DynamoDemoEntity.class)上をIDemoEntity

しかし、それは私の完全な構造を壊す:プロジェクト1は、それがコンパイルされているプラ​​ットフォーム固有のプロジェクト、情報がないものとします。

すべてのアイデア、私はカスタムデシリアライザ(のSpring Beanなどなど)を提供することができるかが、プロジェクト1でプラットフォーム固有の変更を行うことなく?

Sukhpal・シン:

まず、あなたのカスタムを作成する必要がありDynamoDemoEntityDeserializer、以下のように:

class DynamoDemoEntityDeserializer extends JsonDeserializer<DynamoDemoEntity> {
    @Override
    public DynamoDemoEntity deserialize(JsonParser p, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
       // return DynamoDemoEntity instance;
    }
}

そして、あなたはの豆作成することができcom.fasterxml.jackson.databind.Module、以下のように:

@Bean
public Module dynamoDemoEntityDeserializer() {
    SimpleModule module = new SimpleModule();
    module.addDeserializer(IDemoEntity.class, new DynamoDemoEntityDeserializer());
    return module;
}

型com.fasterxml.jackson.databind.Moduleの任意の豆を自動的に自動設定Jackson2ObjectMapperBuilderに登録され、それが作成する任意ObjectMapperインスタンスに適用されます。これは、あなたのアプリケーションに新しい機能を追加するときにカスタムモジュールを貢献するための世界的なメカニズムを提供します。

出典:HOWTO-カスタマイズ・ジャクソン、objectmapper

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=222298&siteId=1