2013-02-06 72 views
1

我使用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。我無法找出導致行爲差異的原因以及解決問題的方法。

+0

它看起來像接收器解碼爲latin1,這是一個配置問題或使用默認編碼代碼問題 – Esailija

+0

@Esailija:接收器是捲曲命令行工具或瀏覽器,都使用UTF-8。我相信這不是接收方的問題。 – divanov

+1

我從你的文章中瞭解到,你有一臺服務器將合法的UTF-8發佈到另一臺服務器上,而另一臺服務器將其解釋並轉儲結果.. – Esailija

回答

1

這個問題有一個非常傷心的原因,它很難找到。 Ant的javac任務有明確的編碼集:

<javac destdir="${classes}" includeantruntime="false" source="1.6" target="1.6" debug="true" encoding="ISO-8859-1" classpathref="main.classpath"> 

有人下一個Tomcat的工作,因爲它是與Eclipse構建和另一個部署與螞蟻建造,破壞所有Unicode字符。

0

如果它工作在7.0.30而不是7.0.23,也許這是一個被發現並修復的錯誤?你檢查了Tomcat changelog看看裏面有沒有東西?

+0

Apache Tomcat 7.0.23的可能性有一個錯誤,所以它不能產生UTF-8響應,我是第一個注意到它太低而不能被認真對待的人。 – divanov