【问题标题】:Deserializing JSON using RestTemplate which can have changing key使用可以更改密钥的 RestTemplate 反序列化 JSON
【发布时间】:2021-11-10 00:56:31
【问题描述】:

我目前正在调用这个 API https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/gbp.json

这有 gbp 的路径参数,然后包含在响应中

{
    "date": "2021-09-14",
    "gbp": {
        // omitted for brevity
    }
}

我正在使用RestTemplate.getForObject 方法发出成功的 GET HTTP 请求,但是我不确定如何输入响应。

我将使用多个不同的路径参数调用此 url。因此,例如https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/eur.json 是有效的,这将导致响应

{
    "date": "2021-09-14",
    "eur": {
        // omitted for brevity
    }
}

因此,它不像在响应上键入 gbp 属性那样容易,如 Map<String, Double> 等。而且我不想为每个可能的响应创建不同的类。

所以我的问题基本上是。我怎样才能输入这个?我尝试在代表数据的类上使用自定义 @JsonDeserialzer 注释,但是因为它不知道有点死胡同的键。

是通过使用自定义ObjectMapper 来实现此目的的唯一方法吗?我可以将密钥传递给客户反序列化器而不是使用注释?

【问题讨论】:

    标签: java spring spring-boot jackson jackson-databind


    【解决方案1】:

    首先,如果您使用的是 spring 框架 5(或切换到 webflux 堆栈),请考虑使用 WebClient 而不是 RestTemplate。

    您不需要自定义ObjectMapper,但可以使用restTemplate.getForEntity 循环属性,例如:

    ResponseEntity<String> response = restTemplate.getForEntity
    ObjectMapper mapper = new ObjectMapper();
    JsonNode root = mapper.readTree(response.getBody());
    Iterator<Map.Entry<String, JsonNode>> it = root.fields();
    while (it.hasNext()) {
      Map.Entry<String, JsonNode> field = it.next();
      System.out.println("key: " + field.getKey());
       
      //Add some logic here ;)
      //Probably you want the second property, if it exists ...
      if (it.hasNext) {
        field = it.next();
        JsonNode currencyNode = field.getValue();
      }
    }
    

    如果您需要或想要一个对象,请尝试@JsonAnySetter - 请参阅 fe。这里Unstable behavior with Jackson Json and @JsonAnySetter

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 2021-11-11
      相关资源
      最近更新 更多