在jackon JSON库中ALLOW_UNQUOTED_FIELD_NAMES

我正在使用jackson库对JSON进行序列化/反序列化。 我需要这个JSON具有尽可能小的尺寸,所以我启用了ALLOW_UNQUOTED_FIELD_NAMESfunction来消除所有引号。 我知道删除引号不是标准的json,但是使json变小是项目的一项硬性要求。 生成的json有效,但是当我尝试读取json值时,我得到一个exception:

org.codehaus.jackson.JsonParseException:意外的字符(’9’(代码57)):期望有效的名称字符(对于不带引号的名称)或双引号(对于引用)在[Source:java.io]处启动字段名称.StringReader @ 1347d75; line:1,column:3]

当我读到这个json时抛出上面的exception:

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

我读它的方式是:

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

我用它来读取和写入值的对象映射器是:

 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); } 

我在发送者和接收者项目中都使用了Jackson的1.6.3版本。 这个function所需的版本是1.2+所以我想也许我没有使用这个版本,但我的接收器是一个Spring应用程序,我检查了libs文件夹中安装的库是1.6.3。

我可能做错了什么? 也许此function不能与地图一起使用。

我有另一个问题,到目前为止我只是发送一个地图,其中键只是一个uuid值,值是一个数字。 如果我发送带有ALLOW_UNQUOTED_FIELD_NAMESfunction的特殊字符的值,可能会有任何问题吗? jackson会逃脱这个角色吗?

谢谢。

看起来像Jackson和QUOTE_FIELD_NAMES在某些情况下会产生这样的输出,即使ALLOW_UNQUOTED_FIELD_NAMES打开也无法自行读取。 您可能需要为非标准输入解析实现自定义JsonParser

问题是您正在生成非标准JSON,并且无法保证客户端将正确处理它。 但是,如果你没有将它暴露在你的应用程序之外并且关心大小,你可以解析/生成像Jackson的Smile这样的二进制格式。 请参阅http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html(2.4 )。

好吧,我认为Pingw33n的答案非常正确。 所以:是的,你可以使用这个function; 但它更具启发性 – 因为没有关于不带引号的名称应该如何工作的规范(毕竟,JSON允许名称的任何和所有字符!); 或者,如果要使用任何逃避机制,那么任何人都应该猜测应该写什么或接受什么。

在这种特殊情况下,可能是“ – ”字符会导致问题。 它不是Javascript名称的合法部分,这是jackson使用的近似值。

一个可能的解决方案是jackson在属性名称中逃避这些字符(我不记得它当前是如何完成的;如果引用了任何名字字符)。 如果你能找到一个简单的测试用例,你可以在Jackson Jira上提交一个Jira请求加强来添加转义(并确保解析器可以解除通常的反斜杠版本)。

我相信这个问题与Javascript sintax有关,而与Jackson和JSON无关。

在Javascript中,名称是一个字母,可选地后跟一个或多个字母,数字或下划线,因此90110a2e-febd-470f-afa4-cf7e890d31b9不是合法的Javascript名称。

如果名称是合法的JavaScript名称而不是保留字,则属性名称周围的引号是可选的。 因此,在“first-name”周围需要引号,但在first_name周围是可选的。

顺便说一句,如果你如此关注JSON大小,为什么不对它进行gzip呢?