【问题标题】:Json String to map convertor,Json String到map转换,
【发布时间】:2018-10-14 04:24:23
【问题描述】:

我正在尝试为嵌套的 JsonObject 编写一个通用代码来映射转换。

我有一个示例 JSONObject

{
  "glossary": {
    "title": "example glossary",
    "GlossDiv": {
      "title": "S",
      "GlossList": {
        "GlossEntry": {
          "ID": "SGML",
          "SortAs": "SGML",
          "GlossTerm": "Standard Generalized \n Markup Language",
          "GlossDef": {
            "para": "A  DocBook.",
            "GlossSeeAlso": [
              "GML",
              "XML"
            ]
          },
          "GlossSee": "markup"
        }
      }
    }
  }
}

我想把它转换成键值为

glossary.title = "example glossary",
glossary.GlossDiv.title = "S",
glossary.GlossDiv.GlossList.GlossEntry.ID ="SGML",
glossary.GlossDiv.GlossList.GlossEntry.SortAs ="SGML",
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm="Standard Generalized 
Markup Language",
glosary.GlossDiv.GlossList.GlossEntry.GlossDef.para ="A  DocBook.",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_0 = "GML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_1 = "XML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSee = "markup"

【问题讨论】:

    标签: java json hashmap


    【解决方案1】:

    这是使用Jackson从json字符串中读取Map的方法:

    public final class JsonUtils {
        public static <T> Map<String, T> readMap(String json) throws Exception {
            if (json == null)
                return null;
    
            ObjectReader reader = new ObjectMapper().readerFor(Map.class);
            MappingIterator<Map<String, T>> it = reader.readValues(json);
    
            if (it.hasNextValue()) {
                Map<String, T> res = it.next();
                return res.isEmpty() ? Collections.emptyMap() : res;
            }
    
            return Collections.emptyMap();
        }
    }
    

    这是使用给定的 utilit 方法从 json 中读取 Map 的方法:

    Map<String, String> map = flatMap(new LinkedHashMap<>(), "", JsonUtils.readMap(json));
    

    最后,这是如何从 Map 转换为所需的 Map (可能这可以在杰克逊引擎中完成,提供自定义反序列化器左右,但我不知道具体如何,这就是为什么它更容易让我手动实现它):

    public static Map<String, String> flatMap(Map<String, String> res, String prefix, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = prefix + entry.getKey();
            Object value = entry.getValue();
    
            if (value instanceof Map)
                flatMap(res, key + '.', (Map<String, Object>)value);
            else
                res.put(key, String.valueOf(value));
        }
    
        return res;
    }
    

    【讨论】:

      【解决方案2】:

      Jackson JSON 是一个非常酷的库,它可以为您做到这一点。我在下面写了一个简单的示例,但您应该能够将其应用于您的 JSONObject。

      假设您有 A.class 和属性 B.class,而后者又拥有嵌套属性 C.class

      @JsonPropertyOrder({ "b" })
      class A {
          @JsonProperty("b")
          public B b;
      
          @JsonProperty("b")
          public B getB() {
              return b;
          }
      
          @JsonProperty("b")
          public void setB(B b) {
              this.b = b;
          }
      }
      
      @JsonPropertyOrder({ "c" })
      class B {
          @JsonProperty("c")
          public C c;
      
          @JsonProperty("c")
          public C getC() {
              return c;
          }
      
          @JsonProperty("c")
          public void setC(C c) {
              this.c = c;
          }
      }
      
      @JsonPropertyOrder({ "d" })
      class C {
          @JsonProperty("d")
          public String d;
      
          @JsonProperty("d")
          public String getD() {
             return d;
          }
      
          @JsonProperty("d")
          public void setD(String d) {
              this.d = d;
          }
      }
      

      您可以像这样将嵌套的 JSONObject {"b":{"c":{"d":"test"}}} 转换为 A.class

      C c = new C();
      c.setD("test");
      
      B b = new B();
      b.setC(c);
      
      JSONObject obj = new JSONObject();
      obj.put("b", b);
      String jsonAsString = new Gson().toJson(obj);
      
      A a = mapper.readValue(jsonAsString, A.class);
      

      同样,您应该能够将您的 JSONObject 转换为您想要的任何类型。希望这会有所帮助

      【讨论】:

      • 我认为这不是会员想要的答案。如果可能的话,您能否将您的输出发布在与问题输入相同的答案中?
      • 感谢 Bhargava 提供 cmets,但这不适用于嵌套的 JSON。我需要对节点进行适当的跟踪。所以这种方法行不通
      • 误读了您的原始问题。对于那个很抱歉。我更新了我的答案。让我知道这是否有帮助。
      • 感谢 oleg.cherednik 的帮助,能否分享您收到的输入和输出,因为我尝试过但没有成功。
      【解决方案3】:
      import com.google.gson.JsonArray;
      import com.google.gson.JsonElement;
      import com.google.gson.JsonObject;
      import com.google.gson.JsonParser;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.Iterator;
      import java.util.List;
      import java.util.Map;
      import java.util.Set;
      
      public class JsonToMapConvertor {
      
          private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
          public static JsonParser parser = new JsonParser();
      
          public static void main(String[] args) throws Exception{
      
          String json ="add your Json";
      
             HashMap<String, Object> map = createHashMapFromJsonString(json,"");        
              for (Map.Entry<String, Object> entry : map.entrySet()) {            
                if(!entry.getValue().toString().contains("{"))  
                      System.out.println(entry.getKey()+" : "+entry.getValue());
              }        
      
         }  
      
      public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) {
      
          JsonObject object = (JsonObject) parser.parse(json);   
          Set<Map.Entry<String, JsonElement>> set = object.entrySet();
          Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
          while (iterator.hasNext()) {
      
              Map.Entry<String, JsonElement> entry = iterator.next(); 
              String key = entry.getKey();
      
              if(prefix.length()!=0){
                  key = prefix + "."+key;
              }
      
              JsonElement value = entry.getValue();
              if (null != value) {            
                  if (!value.isJsonPrimitive()) {
                      if (value.isJsonObject()) {
                          mapReturn.put(key,value);
                          mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
                      } else if (value.isJsonArray() && value.toString().contains(":")) {
      
                          List<HashMap<String, Object>> list = new ArrayList<>();
                          JsonArray array = value.getAsJsonArray();
                          if (null != array) {
                              for (JsonElement element : array) {
                                  list.add(createHashMapFromJsonString(value.toString(),key));
                              }                 
                              mapReturn.put(key, list);
                          }
                      } else if (value.isJsonArray() && !value.toString().contains(":")) {                    
                          mapReturn.put(key, value.getAsJsonArray());
                      }              
                  } else {
                      mapReturn.put(key, value.getAsString());
                  }
              }
          }
          return mapReturn;
          }
      }
      

      【讨论】:

      • 这按预期工作,谢谢 Bhargava Nandibhatla、dkb 和 oleg.cherednik
      • 请将其他人的答案标记为已接受,而不是发布新答案。
      猜你喜欢
      • 2019-05-31
      • 2018-03-22
      • 1970-01-01
      • 2015-01-10
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      相关资源
      最近更新 更多