有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

jackson使用ObjectMapper java API解析JSON字符串

我有一个JSON,如下所示。目标是获得相应的“ip”、“PRODUCTTYPE”和“ID”值

{
    "customerId": "dummy1",
    "nameIdmap": {
        "10.2.1.0": "{PRODUCTTYPE=null, ID=123}",
        "10.2.1.3": "{PRODUCTTYPE=null, ID=456}",
        "10.2.1.4": "{PRODUCTTYPE=null, ID=789}",
        "10.2.1.5": "{PRODUCTTYPE=null, ID=193}"
    }
}

我正在使用ObjectMapperAPI解析和获取这些值

ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(stringToBeParsed);
String customerID = node.get("customerId").asText();
System.out.println("The Customer ID is ::: "+customerID);
JsonNode nameIdmap = node.get("nameIdmap");
StreamSupport.stream(nameIdmap.spliterator(), false).forEach(
        kv -> {
          System.out.println(kv.asText().split(",")[0] +" , 
          "+kv.asText().split(",")[1]);
});

但问题是,我无法获取密钥,在这种情况下,密钥就是ip地址。尝试了不同的方法来实现,但没有得到我想要的

我检查了nameIdmap是否是数组nameIdmap.isArray(),但它是false

我也在下面尝试过,但无法获得ip,即密钥

JsonNode nameIdmap = node.get("nameIdmap"); 
StreamSupport.stream(nameIdmap.spliterator(), false).collect(Collectors.toList())
  .forEach(item -> {
            System.out.println(item.asText());
   });;

共 (3) 个答案

  1. # 1 楼答案

    您可以尝试自定义反序列化程序,如下所示

    1。创建项目类 这是一个POJO,代表一个ID以及字符串和IPItem的映射

    public class SOItem {
        @Override
        public String toString() {
            return "SOItem [id=" + id + ", map=" + map + "]";
        }
        String id;
        Map<String, SOIPItem> map = new HashMap();
    
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public Map<String, SOIPItem> getMap() {
            return map;
        }
        public void setMap(Map<String, SOIPItem> map) {
            this.map = map;
        }
    }
    

    2。创建IPItem类 这是ID和ProductType的POJO

    public class SOIPItem {
        private String type;
        private String id;
    
        public String getType() {
            return type;
        }
        public void setType(String type) {
            this.type = type;
        }
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "SOIPItem [type=" + type + ", id=" + id + "]";
        }
        public SOIPItem(String type, String id) {
            super();
            this.type = type;
            this.id = id;
        }
    }
    

    3。创建自定义反序列化程序

    import java.io.IOException;
    import java.util.Iterator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.ObjectCodec;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
    
    public class SOCustDeser extends StdDeserializer<SOItem> {
    
        public SOCustDeser() {
            this(null);
        }
        public SOCustDeser(Class<?> vc) {
            super(vc);
        }
    
        /**
         * 
         */
        private static final long serialVersionUID = -394222274225082713L;
    
        @Override
        public SOItem deserialize(JsonParser parser, DeserializationContext arg1)
                throws IOException, JsonProcessingException {
            SOItem soItem = new SOItem();
    
            ObjectCodec codec = parser.getCodec();
            JsonNode node = codec.readTree(parser);
    
            soItem.setId(node.get("customerId").asText());
    
            JsonNode idmap = node.get("nameIdmap");
            Iterator<String> fieldNames = idmap.fieldNames();
            while(fieldNames.hasNext()) {
              String ip = fieldNames.next();
              String textValue = idmap.get(ip).asText();
    
              Pattern p = Pattern.compile("(.*?)=(.*?),(.*?)(\\d+)");
              Matcher m = p.matcher(textValue);
              if (m.find()) {
                  soItem.map.put(ip, new SOIPItem(m.group(2), m.group(4)));
              }
            }
    
            return soItem;
        }
    }
    

    4。测试类

    import java.io.File;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    
    public class MicsTest {
        public static void main(String[] args) throws Exception {
            ObjectMapper om = new ObjectMapper();
            SimpleModule sm = new SimpleModule();
            sm.addDeserializer(SOItem.class, new SOCustDeser());
            om.registerModule(sm);
    
            SOItem item = om.readValue(new File("c:\\temp\\test.json"), SOItem.class);
    
            System.out.println(item);
        }
    }
    

    5。产出 SOItem[id=dummy1,map={10.2.1.0=SOIPItem[type=null,id=123],10.2.1.3=SOIPItem[type=null,id=456],10.2.1.5=SOIPItem[type=null,id=193],10.2.1.4=SOIPItem[type=null,id=789]]

  2. # 2 楼答案

    您可以通过nameIdmap获得字段名。getFieldNames作为迭代器。然后你可以这样迭代:

    ...
    Iterator<String> fieldNames = idmap.getFieldNames();
    while(fieldNames.hasNext()) {
      String ip = fieldNames.next();
      String textValue = idmap.get(ip).getTextValue()
      System.out.println(ip + ":" + textValue);
    }
    

    如果嵌套信息也是JSON,那么可以通过idmap进一步访问它。获取(ip)。获取(“ID”);如果没有,那么您仍然可以通过regex找到它,如下所示:

    Pattern p = Pattern.compile("ID=(\\d+)");
    Matcher m = p.matcher(textValue);
    if(m.find()) {
      System.out.println(ip + ":" + m.group(1));
    }
    
  3. # 3 楼答案

    处理这些场景的最佳方法是为json创建一个匹配的pojo。通过这种方式,您可以灵活地处理数据

    创建这样的类

    public class Someclass {
    
        private String customerId;
    
        Map<String, String> nameIdmap;
    
        public Map<String, String> getNameIdmap() {
            return nameIdmap;
        }
    
        public void setNameIdmap(Map<String, String> nameIdmap) {
            this.nameIdmap = nameIdmap;
        }
    
        public Someclass() {
        }
    
        public String getCustomerId() {
            return customerId;
        }
    
        public void setCustomerId(String customerId) {
            this.customerId = customerId;
        }
    }
    

    这段代码将把你的json翻译成SomeClass

    String json = "<copy paste your json here>";
    Someclass someclass = objectMapper.readValue(json, Someclass.class);
    String s = someclass.getNameIdmap().get("10.2.1.0");
    String[] splits = s.split(" ");
    String productType = splits[0].split("=")[1];
    String id = splits[1].split("=")[1];
    System.out.println(productType + "  " + id);