【问题标题】:Conditionally traverse JSON list and deserialise value to Java POJO String有条件地遍历 JSON 列表并将值反序列化为 Java POJO String
【发布时间】:2019-11-15 23:42:47
【问题描述】:

我有以下格式的 JSON 网址列表:

{
  "level": 1,
  "secondLevel": {
    "level": 2,
    "thirdLevel": [
      {
        "level": 3,
        "fourthLevel": {
          "level": 4,
          "fifthLevel": [
            {
              "type": "URLS",
              "listOfimageURLs": [
                {
                  "urlNo": "Num1",
                  "data": "num1Data"
                },
                {
                  "urlNo": "Num2",
                  "data": "num2Data"
                },
                {
                  "urlNo": "Num3",
                  "data": "num3Data"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

最初我有这样的东西,给了我一个 URL 列表,其中包含列表中的所有内容。

@Data
@NoArgsConstructor
public class URLDetail {
  private String type;
  private List<Urls> urlData;
}

现在我正在尝试反序列化以下 Java POJO,并在字段 num2Data 中设置值 urlData

@Data
@NoArgsConstructor
public class URLDetail {
  private String type;
  private String urlData;
}

我试图弄清楚如何有条件地循环遍历 JSON 列表 - url 对于任何等于“Num2”的 urlNo,将关联的“data”字段值(在本例中为“num2Data”)反序列化为 URLDetail POJO 字段 urlData?

我有正常的

mapper.readValue(json, URLDetail.class);

如果我删除 urlData,type 字段设置正确,但完全不确定应用逻辑来解析 JSON 中的 urls 列表。

我需要创建某种自定义反序列化器吗?

【问题讨论】:

标签: java json jackson deserialization pojo


【解决方案1】:

在这种情况下,将JsonPathJackson 一起使用是一个不错的选择。 JsonPath 允许我们在 JSON 有效负载中找到所需的节点,并且在 Jackson 的帮助下,我们可以轻松地将其映射到 POJO

简单示例:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.TypeRef;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;

import java.io.File;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        // Initialize JsonPath to use Jackson
        Configuration.setDefaults(new JacksonDefaultConfiguration());

        String jsonPath = String.format("$..listOfimageURLs[?(@.urlNo == \"%s\")]", "Num2");
        TypeRef<List<URLDetail>> urlDetailsType = new TypeRef<List<URLDetail>>() {
        };
        List<URLDetail> details = JsonPath.parse(jsonFile).read(jsonPath, urlDetailsType);

        details.forEach(System.out::println);
    }
}

class URLDetail {

    @JsonProperty("urlNo")
    private String type;

    @JsonProperty("data")
    private String urlData;

    // getters, setters, toString or lombok annotations
}

class JacksonDefaultConfiguration implements Configuration.Defaults {

    private final JsonProvider jsonProvider = new JacksonJsonProvider();
    private final MappingProvider mappingProvider = new JacksonMappingProvider();

    @Override
    public JsonProvider jsonProvider() {
        return jsonProvider;
    }

    @Override
    public Set<Option> options() {
        return EnumSet.noneOf(Option.class);
    }

    @Override
    public MappingProvider mappingProvider() {
        return mappingProvider;
    }
}

上面的代码打印:

URLDetail{type='Num2', urlData='num2Data'}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 2020-12-10
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多