2016-04-06 17 views
4

次のJSONをJavaオブジェクトに変換する必要があります。 JSONのプロパティproviderResponseにはプロパティのマップが含まれていますが、エスケープされdoublequoteでラップされています。その結果、プロパティproviderResponseをJavaオブジェクトに逆シリアル化しません(Stringとなります)。私はobjectMapper.readValue(msgStr, classType)を使用してJSONを逆シリアル化します。このメッセージは、AWSによってSNS配信ステータス通知用に生成されたもので、JSONメッセージを変更するコントロールはありません。 を設定してプロパティをエスケープ解除し、Stringの代わりにJavaオブジェクトにデシリアライズすることは可能ですか?JSONからJavaオブジェクトへのエスケープされたプロパティの逆シリアル化

{ 
    "delivery":{ 
     "providerResponse":"{\"sqsRequestId\":\"308ee0c6-7d51-57b0-a472-af8e6c41be0b\",\"sqsMessageId\":\"88dd59eb-c34d-4e4d-bb27-7e0d226daa2a\"}" 
    } 
} 

@JsonProperty("providerResponse") 
private String providerResponse; 
+1

私はこれにgsonを使用しました。他のクラスを含め、jsonを定義するクラスを作成する必要があります。つまり、このラベルを文字列として受け入れるのではなく、シリアライザにどのようなオブジェクトであるかを伝える必要があります。 – jdv

+0

thx jdv。 gsonはこれまでこのプロジェクトで使用されていませんでした。レビューします。 – user1573133

+0

ああ、私はジャクソンがJSON <->オブジェクトをマッピングするためのクラスと注釈であるように思われる答えと同じ機能を持っていると仮定しました。 – jdv

答えて

4

この動作をデフォルトで処理するようにObjectMapperを設定する方法はありません。そして、あなたはObjectMapperを使用してJSONをデシリアライズすることができます

public class Wrapper { 
    public Delivery delivery; 
} 

public class Delivery { 
    @JsonDeserialize(using = ProviderResponseDeserializer.class) 
    public ProviderResponse providerResponse; 
} 

public class ProviderResponse { 
    public String sqsRequestId; 
    public String sqsMessageId; 
} 

public class ProviderResponseDeserializer extends JsonDeserializer<ProviderResponse> { 
    private static final ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public ProviderResponse deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { 
     return mapper.readValue(jsonParser.getText(), ProviderResponse.class); 
    } 
} 

:ソリューションは、カスタムJsonDeserializerを作成することです

ObjectMapper mapper = new ObjectMapper(); 
Wrapper wrapper = mapper.readValue(JSON, Wrapper.class); 
+0

thx Casey。魅力のように働く。メッセージを逆シリアル化するたびにObjectMapper()をインスタンス化しても問題ありませんか?それは負荷が重い(1日に100万の直列化解除)システムのパフォーマンスヒットでしょうか? – user1573133

+0

それを聞いてうれしい!私はそれがまったく問題になるとは思わない。しかし、それをインスタンス化したくない場合は、['ObjectMapper'はスレッドセーフです。](http://stackoverflow.com/a/3909846/2446208)、内部で' static'インスタンスを使用することはまったく問題ありませんあなたの 'ProviderResponseDeserializer'(これが好ましい方法と思われるので、答えを更新しました)。 – Casey

+0

@Casey:私も同様の問題があります。私はあなたの解決策を試しました。 '単一の文字列コンストラクタが定義されていません。 'というエラーが表示されます。私はこのエラーの解決策を探しました。私は、引数としてjson文字列を受け取り、そのjsonからプロパティを設定する 'ProviderResponse'クラスのコンストラクタを定義しなければならないことに気付きました。何か案が ? – mantri

0

私はこの同様の問題に直面しました。 ProviderResponseに単一の文字列引数(実際はjson)をとり、コンストラクタ内のjsonをProviderResponseのインスタンスにマップし、このtempインスタンスを使用してプロパティを初期化するコンストラクタを定義すると、これが解決されます。

public class Wrapper { 
    public Delivery delivery; 
} 

public class Delivery { 
    public ProviderResponse providerResponse; 
} 

public class ProviderResponse { 
    public String sqsRequestId; 
    public String sqsMessageId; 

    private static ObjectMapper objMapper = new ObjectMapper(); 

    public ProviderResponse(String json) { 
     ProviderResponse temp = objMapper.readValue(json, ProviderResponse.class); 
     this.sqsMessageId = temp.sqsMessageId; 
     this.sqsRequestId = temp.sqsRequestId; 
    } 
} 

キーは、あなたのユーティリティクラスのどこかにObjectMapperインスタンスとその使用法を維持し、そこからそれを使用することです。

関連する問題