【问题标题】:JsonDeserialize single variables from nested objectJsonDeserialize 嵌套对象中的单个变量
【发布时间】:2020-10-23 21:30:11
【问题描述】:

使用 Java、Spring Boot。

我正在进行一个返回 JSON 的 RestTemplate 调用(针对 GraphQL)。

JSON 响应

{
  "customer_name": "Jon Doe",
  "address": {
    "address_id": 4 
  }
}

我想将嵌套的 addressId 反序列化为 Customer Pojo。这是我目前的做法:

public class Customer implements Serializable {

  @JsonProperty("customer_name")
  private String customerName;

  @JsonDeserialize(using = IdFromAddressDeserializer.class)
  @JsonProperty("address")
  private Integer addressId;

  public Integer getAddressId() { return this.addressId; }
  public void setAddressId(Integer addressId) { this.addressId = addressId; }
public class IdFromAddressDeserializer extends JsonDeserializer<Integer> {

  @Override
  public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        
        // ISSUE p.getText.toString() -> "{"
        // I would expect that I can parse the json for address and extract the id field from the map

        return null;
    }
}

【问题讨论】:

  • 您觉得这有帮助吗?在 Customer.java 中创建一个方法并删除注释 jsonDeserialize 并将忽略未知属性添加到 true。 @JsonProperty("address") private void extractNested(Map&lt;String,Object&gt; address) { this.addressId = (Integer)address.get("address_id"); }

标签: java spring spring-boot jackson graphql


【解决方案1】:

您的 JsonDeserialize-Annotation 似乎是错误的。也许我们有其他版本,但我需要一个“using=”来编译它:

@JsonDeserialize(using=IdFromAddressDeserializer.class)

要从 JsonParser 一次获取完整的字符串,您可以使用...

@Override
public Integer deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

    Sting myJsonStr = parser.readValueAsTree().toString();

    return 0;
}

但考虑让解析器完成工作......这样您就不必自己解析字符串:-)。例如

@Override
public Integer deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

    while (parser.nextToken() != JsonToken.END_OBJECT) {
        if ("address_id".equals(parser.getCurrentName())) {
            parser.nextToken();
            return parser.getIntValue();
        }
    }

    return null;
}

【讨论】:

    【解决方案2】:

    如果做这样的事情它应该自己工作,没有所有的注释。此外,您将地址拼写为带有三个 s 的地址

    restTemplate.getForObject(
            HOST,
            Customer.class,
            Map.of("key", value)
    

    【讨论】:

      猜你喜欢
      • 2019-11-16
      • 1970-01-01
      • 2018-10-20
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多