将 JSON 数组解析为对象集合

Posted

技术标签:

【中文标题】将 JSON 数组解析为对象集合【英文标题】:Parse JSON arrays to collection of objects 【发布时间】:2022-01-16 02:16:47 【问题描述】:

我在将 json 数组解析为指定对象的 java 集合时遇到问题。

JSON 响应:


  "data": [
    
      "country_code": "US", 
      "name": "United States", 
      "supports_region": "true", 
      "supports_city": "true"
    , 
    
      "country_code": "CA", 
      "name": "Canada", 
      "supports_region": "true", 
      "supports_city": "true"
    , 
    
      "country_code": "GB", 
      "name": "United Kingdom", 
      "supports_region": "true", 
      "supports_city": "true"
    
  ]

接下来我要上单国课:

@JsonIgnoreProperties(ignoreUnknown = true)
public class TargetCountry 

    @JsonProperty("country_code")
    private String countryCode;

    @JsonProperty("name")
    private String name;

    public String getCountryCode() 
        return countryCode;
    

    public String getName() 
        return name;
    


我正在使用 Jackson 库将 json 解析为 java。 如果没有包含数组的额外字段“数据”,一切都会好起来的。 由于“数据”字段,我不想制作额外的包装类。如何以优雅的方式解析该响应以接收:Collection<TargetCountry> 例如:

RestTemplate restTemplate = new RestTemplate();
TargetCountry[] countryList = restTemplate.getForObject(uri, TargetCountry[].class);

【问题讨论】:

【参考方案1】:

您可以考虑两种选择:

使用withRootName() 方法为您的rest 模板实例定制Jackson 对象映射器,使其忽略根“数据”节点。您可能需要咨询this question如何自定义映射器。 将结果作为 JsonNode 读取,跳过“数据”路径并将其转换为对象数组。

这里是例子:

public class JacksonRootValue 
    public static final String JSON = "\n" +
            "  \"data\": [\n" +
            "    \n" +
            "      \"country_code\": \"US\", \n" +
            "      \"name\": \"United States\", \n" +
            "      \"supports_region\": \"true\", \n" +
            "      \"supports_city\": \"true\"\n" +
            "    , \n" +
            "    \n" +
            "      \"country_code\": \"CA\", \n" +
            "      \"name\": \"Canada\", \n" +
            "      \"supports_region\": \"true\", \n" +
            "      \"supports_city\": \"true\"\n" +
            "    , \n" +
            "    \n" +
            "      \"country_code\": \"GB\", \n" +
            "      \"name\": \"United Kingdom\", \n" +
            "      \"supports_region\": \"true\", \n" +
            "      \"supports_city\": \"true\"\n" +
            "    \n" +
            "  ]\n" +
            "";

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class TargetCountry 
        @JsonProperty("country_code")
        public String countryCode;
        public String name;

        @Override
        public String toString() 
            return "TargetCountry" +
                    "countryCode='" + countryCode + '\'' +
                    ", name='" + name + '\'' +
                    '';
        
    

    public static void main(String[] args) throws IOException 
        ObjectMapper mapper1 = new ObjectMapper();
        // customize the mapper
        mapper1.setConfig(mapper1.getDeserializationConfig().withRootName("data"));
        TargetCountry[] result1 = mapper1.readValue(JSON, TargetCountry[].class);
        System.out.println("Option 1: " + Arrays.toString(result1));

        // read as a JsonNode and then convert to an object
        ObjectMapper mapper2 = new ObjectMapper();
        JsonNode node = mapper2.readValue(JSON, JsonNode.class);
        TargetCountry[] result2 = mapper2.treeToValue(node.path("data"), TargetCountry[].class);
        System.out.println("Option 2: " + Arrays.toString(result2));
    

输出:

Option 1: [TargetCountrycountryCode='US', name='United States', TargetCountrycountryCode='CA', name='Canada', TargetCountrycountryCode='GB', name='United Kingdom']
Option 2: [TargetCountrycountryCode='US', name='United States', TargetCountrycountryCode='CA', name='Canada', TargetCountrycountryCode='GB', name='United Kingdom']

【讨论】:

以上是关于将 JSON 数组解析为对象集合的主要内容,如果未能解决你的问题,请参考以下文章

gson解析json集合怎么去除属性

ssm框架如何将存有json对象的数组传到后端并接受

怎么把对象数组转换为集合

JSON.Net 将集合序列化为数组数组

怎么将json对象添加进json数组中

JSON数据解析