GSON/JSON:奇怪的特殊字符(变音符号)问题

MrC*_*rCC 5 json diacritics gson

在尝试使用GSON处理JSON响应时(输出来自flickr API,以防你问)我遇到了我所描述的某些特殊字符的奇怪编码:

原始的JSON响应

这是一个十六进制视图:

原始JSON响应的十六进制视图

'u'后跟'双点'就是德国'ü',这就是我的困惑开始的地方.就好像有人拿了这个字母并把它撕成两半,然后对这两个字母进行编码.下图显示了在'ü'被正确编码的情况下我希望它的十六进制编码:

预期的十六进制视图

更奇怪的是,在我预计会出现问题的情况下(即亚洲字符集),一切似乎都很好,例如"标题":"ナガレテユク···"

问题:

  1. 这是reomeonse的一些flickrAPI奇怪或正确的JSON编码吗?或者是相当正确编码的JSON和它的GSON未能将此响应"重组"到原始的'ü'中.或者标题消息的作者是否只是将其搞砸了?
  2. 我如何解决这个问题(如果它是JSON或GSON那些搞乱,如果它是作者,显然不能做任何事情).我如何知道"其他"字符会受到什么影响(ö和ä会浮现在脑海中,但可能会有更多'特殊情况').

Phi*_*art 5

您所看到的是Unicode分解的情况:

像德语变音符号这样的字符可以用两种方式表达:

  • 更传统的预组合形式作为单个字符ü
  • 以分解形式作为基本字符,u然后是组合分音符 ?_(我必须在这里使用下划线才能显示它,因为它不应该单独存在,它实际上只是"悬停点")

如果你收到这样的东西,可以通过使用java.text.Normalizer(从Java 1.6开始提供)轻松转换为预组合形式:

String decomposed = "Mitgef\u0308hl";
printChars(decomposed); // Mitgefühl -- [M, i, t, g, e, f, u, ?, h, l]
String precomposed = Normalizer.normalize(decomposed, Form.NFC);
printChars(precomposed); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]

// Normalizing with NFC again doesn't hurt:
String precomposedAgain = Normalizer.normalize(precomposed, Form.NFC);
printChars(precomposedAgain); // Mitgefühl -- [M, i, t, g, e, f, ü, h, l]
...

static void printChars(String s) {
  System.out.println(s + " -- " + Arrays.toString(s.toCharArray()));
}
Run Code Online (Sandbox Code Playgroud)

如您所见,将NFC应用于已经预先组合的字符串并不会造成伤害.

请注意,打印String将在任何支持Unicode的终端上正确打印,只有在打印字符数组时才能看到分解和预合成表单之间的区别.

可能的来源可能是MacOS,它倾向于以分解形式编码事物,但很奇怪Flickr并没有规范化这些东西.