jackson 使用转义属性的JSON到Java对象的转换

m2xkgtsf  于 4个月前  发布在  Java
关注(0)|答案(3)|浏览(42)

我需要将下面的JSON转换为Java对象。JSON中的属性providerResponse包含属性的Map,但它们被转义并 Package 在doubleQuotes中。因此,它不会将属性providerResponse转换为Java对象(它是String).我使用objectMapper.readValue(msgStr, classType)来格式化JSON。消息是由AWS生成的,用于SNS交付状态通知,我无法控制更改JSON消息。是否可以配置ObjectMapper来取消转义属性并将其转换为Java对象而不是String

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

@JsonProperty("providerResponse")
private String providerResponse;

字符串

ie3xauqp

ie3xauqp1#

默认情况下,似乎没有办法配置ObjectMapper来处理这种行为。解决方案是创建一个自定义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);
    }
}

字符串
然后,您可以使用ObjectMapper将JSON格式化:

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

dgjrabp2

dgjrabp22#

我也遇到过类似的问题。如果我们在ProviderResponse中定义一个构造函数,它接受一个字符串参数(实际上是json),然后将构造函数中的jsonMap到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;
    }
}

字符串
关键是将ObjectMapper示例及其用法保存在您的实用程序类中的某个地方,并从那里使用它。

643ylb08

643ylb083#

虽然@blacktide解决方案看起来很好,但我发现它对我不起作用。可能是因为Scala而不是Java,可能是因为库版本。@blacktide代码对我来说会导致StackOverflow。我使用中间 Package 器类来避免这个问题。测试为“com.fasterxml.Jackson.module”%%“jackson-module-scala”%“2.11.3”。

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer, ObjectMapper}
import com.fasterxml.jackson.databind.annotation.JsonDeserialize

final case class Wrapper(@JsonProperty("delivery") delivery:Delivery)

final case class Delivery(@JsonProperty("providerResponse") providerResponseWrapper: ProviderResponseWrapper) // field name provided to be read as "providerResponse"

@JsonDeserialize(using = classOf[ProviderResponseWrapperDeserializer])
final case class ProviderResponseWrapper(@JsonProperty("providerResponse") providerResponse: ProviderResponse)

final case class ProviderResponse(@JsonProperty("sqsRequestId") sqsRequestId: String, @JsonProperty("sqsMessageId") sqsMessageId: String)

final case class ProviderResponseWrapperDeserializer() extends JsonDeserializer[ProviderResponseWrapper] {
  override def deserialize(jsonParser: JsonParser, deserializationContext: DeserializationContext): ProviderResponseWrapper =
    ProviderResponseWrapper(new ObjectMapper().readValue(jsonParser.getText, classOf[ProviderResponse])) // mapper may be moved to the object
}

字符串
它输出:

Wrapper(Delivery(ProviderResponseWrapper(ProviderResponse(308ee0c6-7d51-57b0-a472-af8e6c41be0b,88dd59eb-c34d-4e4d-bb27-7e0d226daa2a))))


请注意使用annotation为providerResponseWrapper提供正确的名称。

相关问题