Jackson - 在数组中获取一个条目

问题描述 投票:0回答:1

我有以下JSON源。

{
    "my-systems": [{
            "SYSTEM_A": [{
                    "parameter-name": "a_param1",
                    "parameter-display-name": "parameter 1",
                    "optional": "true"
                },
                {
                    "parameter-name": "a_param2",
                    "parameter-display-name": "Parameter 2",
                    "optional": "false"
                }
            ]
        },
        {
            "SYSTEM_B": [{
                    "parameter-name": "b_param1",
                    "parameter-display-name": "Parameter 1",
                    "optional": "true"
                },
                {
                    "parameter-name": "b_param2",
                    "parameter-display-name": "Parameter 2",
                    "optional": "false"
                }
            ]
        }
    ]
}

我想把它读到一个地图上 Map<String, SystemParameter[]>. 我有这样的代码,我真的不知道它是否是我目标的最佳方法。

ArrayNode systemsArr = (ArrayNode)jsonDoc.get("my-systems");
if(systemsArr!= null && !systemsArr.isEmpty()){
    for(JsonNode systemNode : systemsArr ){
        ObjectNode systemObj = (ObjectNode)systemNode;

        System.out.println(systemObj .textValue());
    }
}

它是一个有效的方法吗?我如何获得系统的名称(SYSTEM_A,SYSTEM_B),并将包含的参数转换成一个参数对象数组?

java json jackson
1个回答
1
投票

你只需要在你的依赖关系中使用jackson-databind和jackson-annotations jar,你就可以运行下面的代码。

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonParsing {

    public static void main(String[] args) throws IOException {
        String jsonFilePath = "src/main/resources/source.json"; // JSON File Path
        MySystems mySystems = new ObjectMapper().readValue(new File(jsonFilePath),MySystems.class);

        Map<String,SystemParameter[]> outputMap = new HashMap<>();
        for (Map<String,List<SystemParameter>> map :mySystems.mySystems) {
            for (String key :map.keySet()) {
                outputMap.put(key, map.get(key).toArray(new SystemParameter[0]));
            }
        }
        System.out.println(outputMap);

    }
}

class MySystems {
    @JsonProperty("my-systems")
    List<Map<String,List<SystemParameter>>> mySystems;
}

class SystemParameter {
    @JsonProperty("parameter-name")
    String paramName;

    @JsonProperty("parameter-display-name")
    String paramDispName;

    @JsonProperty("optional")
    String optional;
}

0
投票

如果你所做的只是保持键的唯一性,那么使用数组'my-systems'是没有什么用处的,(我假设你的SYSTEM_A可能不同)。(我假设你的SYSTEM_A可能是不同的).相反,我建议你用下面的方式来格式化JSON数据。

{
  "my-systems": [
    {
      "system-name" : {
        "name":"System_A",
        "parameters": [
          {
            "parameter-name": "a_param1",
            "parameter-display-name": "parameter 1",
            "optional": "true"
          },
          {
            "parameter-name": "a_param2",
            "parameter-display-name": "Parameter 2",
            "optional": "false"
          }
        ]
      }
   }
  ]
}

这个方法很干净,可以让你在'system-name'这个属性下捕捉到系统的名字,而且它的参数是嵌套在里面的。你可以简单地声明一个模型,Jackson(或gson)将简单地处理一切。

如果你宁愿单独解析响应,或者你对响应没有控制权,你可以选择用你的实现,但是你不需要转换为ObjectNode。你可以在你的for循环里面使用下面的样本。

String f2Str = jsonNode.get("f2").asText();
double f2Dbl = jsonNode.get("f2").asDouble();
int    f2Int = jsonNode.get("f2").asInt();
long   f2Lng = jsonNode.get("f2").asLong();

其中'f2'是你的key, 你可以用node.fieldNames().next()来获取key,这实际上是从迭代器中获取属性。

你也可以试试下面的那些,它们似乎更好处理。

JsonNode parent = ...;
for (Iterator<String> it = parent.fieldNames() ; it.hasNext() ; ) {
    String field = it.next();
    System.out.println(field + " => " + parent.get(field));
}
for (Iterator<Map.Entry<String,JsonNode>> it = parent.fields() ;
     it.hasNext() ; ) {
    Map.Entry<String,JsonNode> e = it.next();
    System.out.println(e.getKey() + " => " + e.getValue());
}

最新的例子取自 此处. 希望能帮到你

© www.soinside.com 2019 - 2024. All rights reserved.