简体   繁体   English

使用转义属性的JSON到Java对象反序列化

[英]JSON to Java object deserialization with escaped properties

I need to convert the following JSON to Java object. 我需要将以下JSON转换为Java对象。 The property providerResponse in the JSON contains map of properties but they are escaped and wrapped in doubleQuotes. JSON中的属性providerResponse包含属性的映射,但它们被转义并包装在doubleQuotes中。 As a result, it does not deserialize the property providerResponse into a Java object (it comes as String ). 因此,它不会将属性providerResponse反序列化为Java对象(它以String )。 I use objectMapper.readValue(msgStr, classType) to deserialize the JSON. 我使用objectMapper.readValue(msgStr, classType)来反序列化JSON。 The message is generated by AWS for SNS delivery status notifications and I don't have control to change the JSON message. 该消息由AWS生成,用于SNS传递状态通知,我无法控制更改JSON消息。 Is it possible to configure ObjectMapper to unescape the property and deserialize into a Java object instead of String ? 是否可以将ObjectMapper配置为unescape属性并反序列化为Java对象而不是String

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

@JsonProperty("providerResponse")
private String providerResponse;

There doesn't seem to be a way to configure ObjectMapper to handle this behavior by default. 似乎没有办法配置ObjectMapper来默认处理此行为。 The solution is to create a custom JsonDeserializer : 解决方案是创建自定义JsonDeserializer

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);
    }
}

Then you can deserialize the JSON by using your ObjectMapper : 然后,您可以使用ObjectMapper反序列化JSON:

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

I faced this similar issue. 我遇到了类似的问题。 This gets resolved if we define a constructor in ProviderResponse which takes a single string argument (which is actually json) and then map the json in the constructor to the instance of ProviderResponse and use this temp instance to initialise the properties. 如果我们在ProviderResponse定义一个构造函数,它接受一个字符串参数(实际上是json)然后将构造函数中的json映射到ProviderResponse的实例并使用此临时实例初始化属性,则会解决此问题。

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;
    }
}

The key is to keep the ObjectMapper instance and the its usage somewhere in your utility class and use it from there. 关键是将ObjectMapper实例及其用法保留在实用程序类中的某个位置并从那里使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM