我在Java中使用Jackson2.4来做一些JSON的跑腿工作。我用Apache HttpGet调用远程服务器,用Jackson将结果反序列化为POJO,操作这些结果,然后用Jackson序列化它们,用HttpPost推回远程服务器。
我发现的问题是Jackson正在将unicode字面量转换为unicode字符,由于两端的编码问题,我不需要它这样做。例如,我可能在JSON中有这样的内容:
"field1": "\u00a2"
但是Jackson在反序列化时将“\u00a2”转换为“TM”,这会导致远程服务器出现问题。它必须作为转义的unicode进行维护。(指定UTF-8)或者甚至从我的Web浏览器调用来获取数据,转义的unicode会被保留,所以我知道它是从服务器正确地进来的。如果我让Jackson从响应上的实体消费输入流,它会自动进行转换。
我试过用JsonGenerator写,它被显式设置为UTF-8以写入HttpPost。它不起作用,远程服务器仍然拒绝它。我已经深入研究了ObjectMapper和JsonParser的配置选项,但我没有看到任何可以覆盖这种行为的东西。当然,转义非ASCII,但这不是我在这里需要做的。也许我错过了一些明显的东西,但是我不能让Jackson反序列化这个字符串而不替换转义的unicode。
编辑:好吧,我的错,唯一有问题的字面量有3或5个前导斜杠,而不是一个。这有点奇怪,但Java似乎是在反序列化过程中默认解包的,即使从服务器返回的原始文本保留了它。仍然不知道如何让Java在不检查疯狂数量的文本的情况下保留它。
3条答案
按热度按时间2sbarzqh1#
你所期望的是在Jackosn的作用域之外。它是java在阅读字符串时转换它。出于同样的原因,如果你有一个值为
\u00a2
的属性文件,并使用jdk API读取它,你将得到转换后的值。根据文件大小,可以在将字符串传递给Json之前对char \进行双转义,也可以使用反序列化程序将字符串“转义”回去(仅适用于字符串)和如下内容:谢谢
0ejtzxu12#
另一种自定义Jackson行为的方法是自定义
JsonParser
。关键的方法是
_finishString2()
,它被用来做'decodeEscaped',所以我们可以写一个JsonParser扩展ReaderBasedJsonParser并覆盖_finishString2
方法:完整的演示代码here
igsr9ssn3#
我花了几个小时想办法,终于找到了。
我有一些二进制数据。例如
0xab 0xa6 0xaa
我想我的json看起来像这样:这个json的读取器将去掉
\u00
,并将剩下的内容视为表示二进制数据的十六进制字符串。为了使用JacksonObjectMapper,我准备了一个String对象,其中包含十六进制数据的格式化unicode符号字符串:
然后,我使用:
这样一来,我就再也逃不掉了,我得到了我想要的。