我使用Jersey生成RESTful服務,該服務生成UTF-8編碼的答覆。 下面的代碼片段:HttpServletResponse生成損壞的UTF-8數據
public static class Data {
private String value;
public Data(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response method() {
Data response = new Data("€");
return Response.status(Response.Status.OK)
.type(MediaType.APPLICATION_JSON + ";charset=UTF-8")
.entity(response)
.build();
}
它應該產生如下的答覆:
{"value":"€"}
或字節數組:
[123, 34, 118, 97, 108, 117, 101, 34, 58, 34, -30, -126, -84, 34, 125]
注意,即歐元符號編碼三字節-30,-126,-84或0xe2 0x82 0xac。
然而,它產生以下響應
{"value":"â¬"}
或字節數組:
[123, 34, 118, 97, 108, 117, 101, 34, 58, 34, -61, -94, -62, -126, -62, -84, 34, 125]
。注意,歐元符號被編碼爲六個字節現在-61,-94,-62, -126,-62,-84或0xc3 0xa2 0xc2 0x82 0xc2 0xac。
我發現一個轉換序列,導致這種損壞,在某些時候UTF-8編碼數據被視爲Latin1編碼數據。
Data data = new Data("€");
org.codehaus.jackson.map.ObjectMapper mapper
= new org.codehaus.jackson.map.ObjectMapper();
try {
String strData = mapper.writeValueAsString(data);
System.out.println(strData);
byte[] rawData = mapper.writeValueAsBytes(data);
System.out.println(Arrays.toString(rawData));
String asLatin1 = new String(rawData, "ISO-8859-1");
byte[] brokenUtf8 = asLatin1.getBytes("UTF-8");
System.out.println(Arrays.toString(brokenUtf8));
} catch (IOException e) {
System.out.println("Fail " + e.getMessage());
}
服務兩臺機器上的一個與Apache-Tomcat的7.0.30,另一個在Apache的Tomcat的7.0.23運行。前者產生正確的UTF-8響應,而後者則破壞UTF-8。我無法找出導致行爲差異的原因以及解決問題的方法。
它看起來像接收器解碼爲latin1,這是一個配置問題或使用默認編碼代碼問題 – Esailija
@Esailija:接收器是捲曲命令行工具或瀏覽器,都使用UTF-8。我相信這不是接收方的問題。 – divanov
我從你的文章中瞭解到,你有一臺服務器將合法的UTF-8發佈到另一臺服務器上,而另一臺服務器將其解釋並轉儲結果.. – Esailija