带有德语变音符号的 JSON Jackson + HTTPClient

Posted

技术标签:

【中文标题】带有德语变音符号的 JSON Jackson + HTTPClient【英文标题】:JSON Jackson + HTTPClient with german umlauts 【发布时间】:2013-01-10 00:15:27 【问题描述】:

我遇到了关于 json 字符串的问题,我使用 Apache http 客户端获取,其中包含德语变音符号。

只有在字符串不包含任何德语变音符号时,json 字符串的映射才有效,否则我会收到“JsonMappingException: Can not deserialize instance of [...] out of START_ARRAY。

Apache http 客户端使用“Accept-Charset”设置为 HTTP.UTF-8,但结果我总是得到例如“\u00fc”而不是“ü”。当我手动更换例如"\u00fc" 与 "ü" 映射完美。

如何从 Apache http 客户端获取 utf-8 编码的 json 响应? 还是服务器输出有问题?

params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
httpclient = new DefaultHttpClient(params);
httpclient = new DefaultHttpClient(params);
HttpGet httpGetContentLoad = new HttpGet(url);
httpGetContentLoad.setHeader("Accept-Charset", "utf-8");
httpGetContentLoad.setParams(params);
response = httpclient.execute(httpGetContentLoad);
entity = response.getEntity();
String loadedContent = null;
if (entity != null)

   loadedContent = EntityUtils.toString(entity, HTTP.UTF_8);
   entity.consumeContent();

if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode())

    throw new Exception("Loading content failed");

closeConnection();
return loadedContent;

而json代码映射到这里:

String jsonMetaData = loadGetRequestContent(getLatestEditionUrl(newspaperEdition));
Newspaper loadedNewspaper = mapper.readValue(jsonMetaData, Newspaper.class);
loadedNewspaper.setEdition(newspaperEdition);

更新 1: JsonMetaData 是包含获取的 json 代码的 String 类型。

更新2:

我用来将 json 输出转换为我需要的这段代码:

public static String convertJsonLatestEditionMeta(String jsonCode)

    jsonCode = jsonCode.replaceFirst("\\[\"[A-Za-z0-9-[:blank:]]+\",\\", "\"edition\":\"an-a1\",");
    jsonCode = jsonCode.replaceFirst("\"pages\":\\", "\"pages\":\\[");
    jsonCode = Helper.replaceLast(jsonCode, "]", "]");
    jsonCode = jsonCode.replaceAll("\"[\\d]*\"\\:\\\"", "\\\"");
    return jsonCode;

更新3: Json转换示例:

转换前的jsoncode:

["Newspaper title",

    "date":"20130103",
"pages":
            
            "1":  "ressort":"ressorttitle1","pdfpfad":"pathToPdf1","number":1,"size":281506,
            "2":"ressort":"ressorttitle2","pdfpfad":"pathToPdf2","number":2,"size":281533,
            [...]
        
    
]

转换后的Jsoncode:

   
"edition":"Newspaper title",
"date":"20130103",
    "pages":
    [
       "ressort":"Resorttitle1","pdfpfad":"pathToPdf1","number":1,"size":281506,
       "ressort":"Resorttitle2","pdfpfad":"pathToPdf2","number":2,"size":281533,
       [...]
    ]

解决方案: 我按照@Boris 的建议开始使用 GSON,关于变音符号的问题已经消失了!更多的 GSON 似乎确实比 Jackson Json 更快。

解决方法是手动替换此表后面的字符:

Sign        Unicode representation

Ä, ä        \u00c4, \u00e4
Ö, ö        \u00d6, \u00f6
Ü, ü        \u00dc, \u00fc
ß           \u00df
€           \u20ac

【问题讨论】:

出于好奇,如果您尝试将树(使用mapper.readTree)读取到JsonNode,它会起作用还是您也有错误?如果出错,是哪一个? 另外,.readValue()很多 个重载——jsonMetaData 这里的参数类型是什么? 您好,感谢您的快速回复。对 JsonNode 使用 mapper.Tree 会引发相同的异常。 JsonMetaData 是字符串类型。问题是否与服务器有关,因为它无法返回 utf-8 编码的 jsondata? 【参考方案1】:

尝试这样解析:

entity = response.getEntity();
Newspaper loadedNewspaper=mapper.readValue(entity.getContent(), Newspaper.class);

没有理由经过String,Jackson 直接解析InputStreams。如果您使用我提出的方法,Jackson 也会自动检测编码。

EDIT 顺便考虑使用GSON JSON 解析库。它甚至比杰克逊更快,更易于使用。不过,Jackson 最近也开始解析 XMl,这是一个优点。

EDIT2 毕竟您已经添加了详细信息,我想问题出在服务的服务器实现上 - 元音变音不能在 json 中进行 unicode 转义 - UTF 8 是本机编码它。你为什么不通过正则表达式来代替manually replace e.g. "\u00fc" with "ü"

【讨论】:

我无法使用您提出的方法,因为在映射 jsonstring 之前,它会通过字符串替换进行转换,以满足我对对象映射的需求。这是必要的,因为服务器端的 api 很差。但是 EntityUtils.toString(entity, HTTP.UTF_8);应该为 Json Jackson 返回一个正确的编码字符串,不是吗? GSON Json 对我来说很好,但我很好奇为什么它不能在当前配置中工作。 @alex 虽然我接受你的解释,但我想问一下你对字符串做了什么样的操作?我在问,因为我有上帝的感觉,即使使用我提出的方法,我也能帮助你完成它们。我遇到过很多次和你类似的情况。另外,我仍然认为去String 是错误的方式。 好的,听起来很棒。我做了一个转换,以弥补 api 对面向对象的理解不足,将其映射到我的 java 对象,并附上我上面的帖子。 @alex 谢谢,我可以请你也发布正则表达式的简短示例。我想你可以想象,即使我可以尝试理解它们,它们也不是那么容易理解的。我相信例子会帮助我。 @alex Dude,我不知道谁想到了那些服务,但这根本不是json服务!

以上是关于带有德语变音符号的 JSON Jackson + HTTPClient的主要内容,如果未能解决你的问题,请参考以下文章

带有德语变音符号的 iOS 上的 FacebookDisplayName

带有变音符号的 xcodebuild 目标名称

CakePHP 2.1:德语变音符号的 Sluggable 行为

Python2 / Windows7:打开包含德语变音符号的文件名

使用 utf8_general_ci 排序规则和 utf8 字符集服务器的德语变音符号的搜索结果区分大小写

UTF-8 解码变音符号偶尔会失败