ALLOW_UNQUOTED_FIELD_NAMES in jackon JSON library

2019-01-15 07:02发布

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.

3条回答
\"骚年 ilove
2楼-- · 2019-01-15 07:14

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?

查看更多
Rolldiameter
3楼-- · 2019-01-15 07:22

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).

查看更多
Rolldiameter
4楼-- · 2019-01-15 07:25

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).

查看更多
登录 后发表回答