将JSON编码/解码为java.util.Map的库?

15

有没有人知道一个Java库,可以轻松地将Java Maps编码为JSON对象,反之亦然?

更新

由于某些无法解释的原因(我有时候很讨厌这种情况),我无法在我的环境中使用泛型。

我想要做的是像这样:

Map a = new HashMap();
a.put( "name", "Oscar" );

Map b = new HashMap();
b.put( "name", "MyBoss"); 
a.put( "boss",  b ) ;


List list = new ArrayList();
list.add( a );
list.add( b );


 String json = toJson( list );
 // and create the json:
 /*
    [
       {
         "name":"Oscar",
         "boss":{
              "name":"MyBoss"
         }
        },
        {
            "name":"MyBoss"
        }
     ]

  */ 

并且能够再次将其作为一组映射列表。

 List aList = ( List ) fromJson( jsonStirng );

参见:http://stackoverflow.com/questions/338586/a-better-java-json-library - Taylor Leese
请参阅以下链接:https://dev59.com/pXRB5IYBdhLWcg3w-8Lo,https://dev59.com/RHI-5IYBdhLWcg3wO1vl和https://dev59.com/InRB5IYBdhLWcg3wUV1d。 - dma_k
@dma_k 感谢您提供的参考。实际上我需要像最后一个那样的东西,因为我并不想绑定到一个bean上。 - OscarRyz
6个回答

33

你可以使用Google Gson来实现这个功能。它对泛型有很好的支持。

以下是一个SSCCE示例:

package com.stackoverflow.q2496494;

import java.util.LinkedHashMap;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class Test {

   public static void main(String... args) {
        Map<String, String> map = new LinkedHashMap<String, String>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");
        Gson gson = new Gson();

        // Serialize.
        String json = gson.toJson(map);
        System.out.println(json); // {"key1":"value1","key2":"value2","key3":"value3"}

        // Deserialize.
        Map<String, String> map2 = gson.fromJson(json, new TypeToken<Map<String, String>>() {}.getType());
        System.out.println(map2); // {key1=value1, key2=value2, key3=value3}
    }

}

有没有一种方法可以将反序列化为非泛型映射? - OscarRyz
要么将 Map<String, String> 替换为 Map<String, Object>Map<Object, Object>。或者,更符合面向对象的方式是使用一个完整的 JavaBean。Gson 也可以完美地处理它。请参见此答案以获取示例:https://dev59.com/rHI-5IYBdhLWcg3wwbZM#1688182 - BalusC
问题是我正在使用一个不支持泛型的环境(嗯,不要问我为什么,我只是不能使用它们),我想找到一种将普通的映射列表转换为JSON并将其还原的方法。 - OscarRyz
我明白了。它是否以任何方式运行Java 1.5?否则,Gson无论如何都无法运行。您可以考虑查看Jackson:http://jackson.codehaus.org/(此处有教程http://jackson.codehaus.org/Tutorial,“Ctrl + F”上的“untyped”可实现您想要的相同效果)。顺便说一下,我建议使用Jackson是因为它快速。此外,这里有基准测试:http://www.cowtowncoder.com/blog/archives/2009/02/entry_204.html - BalusC
1
非常棒的答案。我完全错过了TypeToken类,也想不起自己哪里出错了。谢谢。 :) - Lyubomyr Shaydariv

14

JSON-Simple 看起来相对容易使用(以下是示例)。

将 Map 转换为 JSON:

  Map map = new HashMap();
  map.put("name", "foo");
  map.put("nickname", "bar");
  String jsonText = JSONValue.toJSONString(map);

将JSON转换为List/Map:

  String s = yourJsonString;
  List list = (JSONArray) JSONValue.parse(s);       
  Map map = (JSONObject) list.get(0);

这个做了工作。我更喜欢Gson进行bean绑定,但不幸的是在我的环境中,我无法使用Gson严重依赖的泛型。JSON-Simple有一个小错误,我认为可以很容易地解决:http://code.google.com/p/json-simple/issues/detail?id=18。无论如何,我仍在使用它,感谢提供链接。 - OscarRyz
说实话,我认为即使在使用GSON时也不一定需要使用泛型。我非常确定它也能正常工作。 - StaxMan
经过数小时的搜索,我终于得到了答案,非常感谢。 - chitraketu Pandey

4
您可以访问Json.org网站,查看Java中优秀的JSON库列表。JSon.org自己的实现 JSONObject可以轻松实现此功能。请参考他们的JavaDoC。
 /**
     * Construct a JSONObject from a Map.
     * 
     * @param map A map object that can be used to initialize the contents of
     *  the JSONObject.
     */
    public JSONObject(Map map);

你可以做

JSONObject json = new JSONObject(map);

将JSON字符串转换回对象的方法如下:

String jsonString = "{\"name\" : \"some name\", \"age\" : 10}";
JSONObject json = new JSONObject(jsonString);

你可以访问像这样的值:

int age = json.getInt("age");

JavaDoC构造函数

从源JSON文本字符串构造JSONObject。这是最常用的JSONObject构造函数。

参数:source-以左大括号{开头,右大括号}结尾的字符串。


这个涉及到从Map到JSONObject的转换,但是提问者想要双向转换。 - ThomasW

3

我想真正的问题应该是哪个JSON库(来自org.json的页面)不允许这样做。据我所知,那里的每个库都会以某种形式允许这样做。因此,到目前为止提到的每个库都可以使用。

另外,值得一提的是,Jackson 可以很好地处理各种数据,包括基本的 Maps 和 Lists:

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValue(list);
List listOfMaps = mapper.readValue(json, List.class);

这种情况可以使用特定的处理方式。虽然可以使用通用类型信息,但在使用JDK容器类型的“自然”绑定时是可选的。


1

0

使用Google Gson时。

var getRowData =
[{
    "dayOfWeek": "Sun",
    "date": "11-Mar-2012",
    "los": "1",
    "specialEvent": "",
    "lrv": "0"
},
{
    "dayOfWeek": "Mon",
    "date": "",
    "los": "2",
    "specialEvent": "",
    "lrv": "0.16"
}];

    JsonElement root = new JsonParser().parse(request.getParameter("getRowData"));
     JsonArray  jsonArray = root.getAsJsonArray();
     JsonObject  jsonObject1 = jsonArray.get(0).getAsJsonObject();
     String dayOfWeek = jsonObject1.get("dayOfWeek").toString();

// 使用Jackson时

    JsonFactory f = new JsonFactory();
              ObjectMapper mapper = new ObjectMapper();
          JsonParser jp = f.createJsonParser(getRowData);
          // advance stream to START_ARRAY first:
          jp.nextToken();
          // and then each time, advance to opening START_OBJECT
         while (jp.nextToken() == JsonToken.START_OBJECT) {
            Map<String,Object> userData = mapper.readValue(jp, Map.class);
            userData.get("dayOfWeek");
            // process
           // after binding, stream points to closing END_OBJECT
        }

如果你认为同样的答案适用于多个问题,也许它们是重复的,应该标记为重复,你不觉得吗? - Denys Séguret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接