Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ALLOW_UNQUOTED_FIELD_NAMES in jackon JSON library

I'm using the jackson library for serializing/deserializing to/from JSON. I need that this JSON has the smallest size as possible so I've enabled the feature ALLOW_UNQUOTED_FIELD_NAMES to eliminate all the quotes. I know that removing quotes is not standard json, but making json small is a hard requirement of the project. The generated json works, but when I've trying to read the json value I'm getting an exception:

org.codehaus.jackson.JsonParseException: Unexpected character ('9' (code 57)): was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name at [Source: java.io.StringReader@1347d75; line: 1, column: 3]

The exception above is thrown when I read this json:

{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1}

The way I read it is:

Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {});

and the object mapper I use both for reading and writing the values is:

private static final ObjectMapper om = new ObjectMapper();
static {
    om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
    om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true);
    om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
}

I'm using version 1.6.3 of Jackson, in both the sender and the receiver projects. The needed version for this feature is 1.2+ so I thought that maybe I wasn't using this version, but my receiver is a Spring application and I've checked that the library installed in libs folder is 1.6.3.

What may I be doing wrong? Maybe this feature cannot be used with maps.

I have another question, So far I'm just sending a map where the key is just a uuid value and the value is a number. May I have any problems if I send a value with special characters with ALLOW_UNQUOTED_FIELD_NAMES feature on? Will jackson escape this characters?

Thanks.

like image 842
Javi Avatar asked Jan 27 '11 10:01

Javi


3 Answers

Ok, Pingw33n's answer is pretty much correct I think. So: yes, you can use the feature; but it is rather heuristic -- since there is no specification as to how unquoted names should work (after all, JSON allows any and all characters for names!); or, what if any escape mechanism is to be used, it's anyone's guess as to what should be written or accepted.

In this particular case it is probably '-' character that causes an issue. It is not a legal part of Javascript name, which is the approximation Jackson uses.

One possible solution would be for Jackson to escape such characters in property names (I don't remember how it is done currently; if any name characters are quoted). If you can figure out a simple test case, you can file a Jira request-for-enchancement at Jackson Jira to get escaping added (and ensure parser can unescape the usual backslash version).

like image 114
StaxMan Avatar answered Oct 11 '22 04:10

StaxMan


Seems like Jackson with QUOTE_FIELD_NAMES in certain cases produces such output that it can't read itself even with ALLOW_UNQUOTED_FIELD_NAMES on. You will probably need to implement custom JsonParser for non-standard input parsing.

The problem is that you're generating non-standard JSON and there's no guarantees that client will handle it properly. However if you don't expose it outside your application(s) and care about size much you could parse/generate binary format like Jackson's Smile. See http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).

like image 45
pingw33n Avatar answered Oct 11 '22 03:10

pingw33n


I believe the problem is related to Javascript sintax and not to Jackson nor JSON.

In Javascript a name is a letter optionally followed by one or more letters, digits, or underbars, so 90110a2e-febd-470f-afa4-cf7e890d31b9 is not a legal Javascript name.

The quotes around a property's name are optional if the name would be a legal JavaScript name and not a reserved word. So quotes are required around "first-name", but are optional around first_name.

BTW, if you are so concerned about JSON size why don't you gzip it?

like image 40
Javier Ferrero Avatar answered Oct 11 '22 02:10

Javier Ferrero