Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't parse JSON property "null"

I faced with one trouble when tried to parse JSON "null" property, please help me to understand what's the real problem. I had a following JSON:

{
  "properties" : {        
    "null" : {
      "value" : false
    }
  }
}

I used http://jsonlint.com to validate that this JSON is valid. I tried to parse it from java:

import net.sf.json.JSONObject;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        String st = "{" +
                "      'properties' : {" +
                "        'null' : {" +
                "          'value' : false" +
                "        }" +
                "      }" +
                "}";
        JSONObject.fromObject(st);
    }
}

But got the exception:

Exception in thread "main" java.lang.ClassCastException: JSON keys must be strings.
    at net.sf.json.JSONObject._fromJSONObject(JSONObject.java:927)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:155)
    at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:108)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:238)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
    at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
    at net.sf.json.JSONObject.element(JSONObject.java:1786)
    at net.sf.json.JSONObject._fromJSONTokener(JSONObject.java:1036)
    at net.sf.json.JSONObject._fromString(JSONObject.java:1201)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:165)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:134)

I used json-lib-2.4-jdk15.jar from http://json-lib.sourceforge.net to parse it. Could anybody please clarify this? Why this library throws exception, but online validator said that it's valid JSON? It is a bug in the library or I made something wrong?

like image 325
erkfel Avatar asked Apr 17 '26 00:04

erkfel


1 Answers

JSON-lib initially parses and populates a Java Map with the input JSON. Unfortunately, JSON-lib then checks whether every JSON object element name is a JSON null. It's null check is performed in the JSONNull.equals(Object) method. This method returns true for a "null" JSON string, which of course is not actually a JSON null value.

I recommend filing a bug with the JSON-lib project for this issue. The implementation of JSONNull.equals(Object) is flawed.

Unfortunately, it's not possible to handle this with a custom PropertyNameProcessor.

Options available for a more immediate solution include altering the JSON-lib code yourself, or switching libraries.

If you can switch libraries, I highly recommend Jackson. Following is an example of using it to deserialize the example JSON in the original question.

/*
{
  "properties" : {        
    "null" : {
      "value" : false
    }
  }
}
 */
String json = "{\"properties\":{\"null\":{\"value\":false}}}";

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(json, Map.class);
System.out.println(map);
// output: {properties={null={value=false}}}

Map<String, Object> propertiesMap = (Map) map.get("properties");
System.out.println(propertiesMap);
// output: {null={value=false}}

Map<String, Object> nullMap = (Map) propertiesMap.get("null");
System.out.println(nullMap);
// output: {value=false}
like image 105
Programmer Bruce Avatar answered Apr 19 '26 14:04

Programmer Bruce