15

Does anyone knows a java library that could easily encode java Maps into json objects and the other way around?

UPDATE

For reasons couldn't explain ( and I hate sometimes ) I can't use generics on my environment.

What' I'm trying to do is to have something like this:

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"
        }
     ]

  */ 

And be able to have it again as a list of maps

 List aList = ( List ) fromJson( jsonStirng );
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • See also: http://stackoverflow.com/questions/338586/a-better-java-json-library – Taylor Leese Mar 22 '10 at 23:37
  • See also http://stackoverflow.com/questions/443499/json-to-map and http://stackoverflow.com/questions/1957406/generate-java-class-from-json and http://stackoverflow.com/questions/658936/is-there-a-library-to-convert-java-pojos-to-and-from-json-and-xml – dma_k Mar 24 '10 at 23:14
  • @dma_k Thanks for the reference. I actually neede something like the last one because I didn't meant to bind to a bean. – OscarRyz Mar 24 '10 at 23:37

6 Answers6

33

You can use Google Gson for that. It has excellent support for Generic types.

Here's an 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}
    }

}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Is there a way to decode ( deserialize ) to non generic map ? – OscarRyz Mar 23 '10 at 17:54
  • Either replace `Map` by `Map` or `Map`. Or, more OO-friendly, just use a fullworthy Javabean. Gson can handle it perfectly as well. See this answer for an example: http://stackoverflow.com/questions/1688099/converting-json-to-java/1688182#1688182 – BalusC Mar 23 '10 at 18:00
  • The problem is I'm using an environment that doesn't support generics, ( erhmm. don't ask me how or why, I just, can't use them ) and what I'm trying to find is a way to convert plain lists of maps to json and have them back. – OscarRyz Mar 23 '10 at 18:17
  • I see. Does it run Java 1.5 at any way? Else Gson won't run at any way. You may consider to have a look at Jackson then: http://jackson.codehaus.org/ (tutorial here http://jackson.codehaus.org/Tutorial, `Ctrl+F` on "untyped" to achieve the same what you want). The reason I suggest Jackson is by the way because it is **fast**. Benchmarks here BTW: http://www.cowtowncoder.com/blog/archives/2009/02/entry_204.html – BalusC Mar 23 '10 at 18:25
  • 1
    Awesome answer. I've totally missed the TypeToken class, and could't remember what I did wrong. Thank you. :) – Lyubomyr Shaydariv Aug 07 '10 at 14:50
14

JSON-Simple looks relatively easy to use (examples below).

Map to JSON:

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

JSON to List/Map:

  String s = yourJsonString;
  List list = (JSONArray) JSONValue.parse(s);       
  Map map = (JSONObject) list.get(0);
Taylor Leese
  • 51,004
  • 28
  • 112
  • 141
  • This one did the work. I like Gson better for bean binding but unfortunately in my environment I can't use generics on which Gson relies heavily. JSON-Simple have a little bug though which I think could be easily solved: http://code.google.com/p/json-simple/issues/detail?id=18 I'm using this anyway, thanks for the link – OscarRyz Mar 24 '10 at 16:01
  • For what it's worth, I don't think you have to use generics even with GSON -- I am pretty sure it, too, would work. – StaxMan Nov 04 '10 at 00:12
  • Thanks a lot after hours of searching i got an answer – chitraketu Pandey Jul 11 '16 at 16:20
4

You can view the site from Json.org for the list of good JSON libraries in Java.

JSon.org's own implementation JSONObject can do just that. From their 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);

you can do

JSONObject json = new JSONObject(map);

To convert JSON String back to object....

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

and you can access values like:

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

Constructor JavaDoC

Construct a JSONObject from a source JSON text string. This is the most commonly used JSONObject constructor.

Parameters: source A string beginning with { (left brace) and ending with } (right brace).

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
3

I guess the real question would be which JSON library (from org.json's page) would NOT allow doing this. As far as I know every single library there would allow this in some form. So every library mentioned so far works.

And to add some information, Jackson works very well with all kinds of data including basic Maps and Lists:

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

which would handle this particular case. While generic type information can be used, it is optional when using "natural" binding to JDK container types.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
1

We use http://json-lib.sourceforge.net/ in our project, it works just fine.

Lluis Martinez
  • 1,963
  • 8
  • 28
  • 42
0

When using 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();

// when using 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
        }
Arun Pratap Singh
  • 3,428
  • 30
  • 23
  • If you think the same exact answer applies to more than one question, maybe they're duplicate and should be flagged as such, don't you think ? – Denys Séguret Jun 03 '14 at 08:51