我正在使用jackson库进行JSON的序列化/反序列化。我需要这个JSON具有尽可能小的大小,所以我启用了ALLOW_UNQUOTED_FIELD_NAMES功能来消除所有引号。我知道删除引号不是标准json,但使json变小是项目的一个硬性要求。生成的json工作正常,但当我试图读取json值时,我遇到了一个异常:
org.codehaus.jackson.JsonParseException:意外字符('9 '(代码57)):字段名的开头应为有效的名称字符(对于不带引号的名称)或双引号(对于带引号的名称)[源:字符串读取器@1347d75;行:1,列:3]
当我读到这个json的时候,上面的异常被抛出:
{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1}
我是这么读的:
Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {});
我用来读写这些值的对象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);
}
我使用的是1.6.3版本的Jackson,在发送器和接收器项目中。这个功能所需的版本是1.2+,所以我想也许我没有使用这个版本,但我的接收器是一个Spring应用程序,我已经检查了安装在libs文件夹中的库是1.6.3。
我可能做错了什么?也许这个功能不能和Map一起使用。
我还有另一个问题,到目前为止,我只是发送了一个Map,其中的键只是一个uuid值,而值是一个数字。如果我发送了一个带有特殊字符的值,并且打开了ALLOW_UNQUOTED_FIELD_NAMES功能,会有什么问题吗?jackson会转义这些字符吗?
谢谢。
6条答案
按热度按时间fykwrbwg1#
好的,我认为Pingw 33 n的答案非常正确。是的,您可以使用该功能;但它是相当启发式的--因为没有规范说明不带引号的名称应该如何工作(毕竟,JSON允许名称使用任何字符!);或者,如果要使用任何转义机制,那么任何人都可以猜测应该编写或接受什么。
在这种特殊情况下,可能是“-”字符导致了问题。它不是Javascript名称的法律的部分,这是Jackson使用的近似值。
一个可能的解决方案是Jackson在属性名中转义这样的字符(我不记得目前是怎么做的;如果你能想出一个简单的测试用例,你可以在Jackson Jira上提交一个Jira增强请求来添加转义(并确保解析器可以取消常用的反斜杠版本)。
cxfofazt2#
看起来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)。
jfgube3f3#
我相信这个问题与Javascript sintax有关,而与Jackson和JSON无关。
在Javascript中,名称是一个字母,后面可以跟一个或多个字母、数字或下划线,因此90110 a2 e-febd-470 f-afa 4-cf 7 e890 d31 b 9不是法律的的Javascript名称。
如果属性名称是法律的的JavaScript名称而不是保留字,则属性名称周围的引号是可选的。因此,“first-name”周围需要引号,但first_name周围的引号是可选的。
顺便说一句,如果你这么关心JSON的大小,为什么不gzip呢?
aij0ehis4#
这是一个老问题,但是如果有人在这里遇到了问题,并且想知道一种方法来让ALLOW_UNQUOTED_FIELD_NAMES在较新版本的Jackson中工作,请使用以下命令:
inb24sb25#
如果您使用的是
Spring Boot
,则可以自动连接ObjectMapper
:gudnpqoy6#
以防有人查到:在新版本的Jackson中,有
JsonMapper.builder()
。所有尝试摆弄objectMapper.deserializationConfig
的尝试对我来说都失败了。这起作用了: