0

What's the best way to deserialize this Json object?

{
    "key1" : "val1",
    "key2" : "blank"
}

into a java hashmap, where the string blank is replaced with null?

   {
        "key1" : "val1",
        "key2" : null
   }

I am currently using Jackson for deserialization.

indieman
  • 1,051
  • 2
  • 11
  • 24
  • You can try implementing your own JsonDeserializer, then add this serializer for you class via new SimpleModule().addSerializer(YourClass.class, new YourDeserializer());, register that module on the object mapper. Take a look at JsonCodec.treeToValue to find where to put your replacement logic. –  Oct 11 '16 at 22:01

2 Answers2

0

You will find part of the answer here.

You just need to manipulate the line inside the while loop:

Object value;
if (object.get(key).equals("blank")) {
    value = "null";
} else {
    value = object.get(key);
}

and make print out will give:

System.out.println(map.get("key1")); // returns val1
System.out.println(map.get("key2")); // returns null

You final code will look like this, and you might need to import the proper .jar files:

import com.orsoncharts.util.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.toList;

public class JsonAnswerOne {

    public static void main(String[] args) throws JSONException {

        String input = "{\n" +
                "    \"key1\" : \"val1\",\n" +
                "    \"key2\" : \"blank\"\n" +
                "}";

        parse(input);
    }

    private static void parse(String input) throws JSONException {
        JSONObject mainObject = new JSONObject(input);
        Map<String, Object> map = jsonToMap(mainObject);
        System.out.println(map.get("key1")); // returns val1
        System.out.println(map.get("key2")); // returns null
    }

    private static Map<String, Object> jsonToMap(JSONObject json) throws JSONException {
        Map<String, Object> retMap = new HashMap<String, Object>();

        if (json != JSONObject.NULL) {
            retMap = toMap(json);
        }
        return retMap;
    }

    private static Map<String, Object> toMap(JSONObject object) throws JSONException {
        Map<String, Object> map = new HashMap<String, Object>();

        Iterator<String> keysItr = object.keys();
        while (keysItr.hasNext()) {
            String key = keysItr.next();
            Object value;
            if (object.get(key).equals("blank")) {
                value = "null";
            } else {
                value = object.get(key);
            }

            if (value instanceof JSONArray) {
                value = toList((JSONArray) value);
            } else if (value instanceof JSONObject) {
                value = toMap((JSONObject) value);
            }
            map.put(key, value);
        }
        return map;
    }

}
Community
  • 1
  • 1
Maytham Fahmi
  • 31,138
  • 14
  • 118
  • 137
0

I tried this and ended up with this:

// use of the deserializer
String json = "{\"key1\":\"val1\",\"key2\":\"blank\"}";
ObjectMapper mapperMap = new ObjectMapper();
SimpleModule moduleMap = new SimpleModule();
moduleMap.addDeserializer(Map.class, new MapDeserializer());
mapperMap.registerModule(moduleMap);
Map map = mapperMap.readValue(json, Map.class);

// custom deserializer
public class MapDeserializer extends StdDeserializer<Map<String, String>> {

    public MapDeserializer() {
        this(null);
    }

    public MapDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Map<String, String> deserialize(JsonParser jp, DeserializationContext context)
            throws IOException {
        // definitely not the best way but it works...
        Map<String, String> map = new HashMap<>();
        String[] keys = new String[] {"key1", "key2"};

        JsonNode node = jp.getCodec().readTree(jp);
        String value;
        for (String key : keys) {
            value = node.get(key).asText();
            if (value.equals("blank")) {
                value = null;
            }
            map.put(key, value);
        }
        return map;
    }
}

Full example solution with an additional example to deserialize the JSON into another class:
https://gist.github.com/audacus/e70ce0f3cd4b17197d911769e05b237e

audacus
  • 3
  • 1
  • 4