2016-07-26 27 views
1

我已經創建了一個Java程序(REST)服務。整個開發/測試是在Windows上完成的,現在部署到生產測試正在進行。然而,有「小」編碼的問題出現了:Java字符串編碼 - 與Windows不同的Linux

String s3 = new String("grün".getBytes(), "UTF-8"); 
logger.info(s3); 
logger.info("das ist wirklich grün"); 
logger.info(new String("das ist wirklich grün".getBytes("UTF-8"), "UTF-8")); 

我通過HTTP屬性(Web應用程序託管在tomcat的,具有權威性的插件Apache的背後)我必須處理幾個值接收。它們的編碼方式與您在第1行中看到的一樣。(此值顯示在Windows和Linux上)。

當我把它轉換爲UTF-8就像在第1行並寫入日誌文件(log4j)我的Windows機器上有「grün」(這是正確的)。在Linux服務器上,我仍然有相同的輸出。

然後我試着直接使用Umlaute(üäöetc),就像第2行一樣,並且在Windows和Linux上這兩個值都被正確寫入日誌文件。然後,我嘗試像第3行那樣進行一些轉換,但結果相同:兩個操作系統都顯示相同的結果。

兩臺機器都具有相同的Java語言環境(Locale.getDefault()) - >我已經試過了。我無法改變將值插入到HTTP請求中的方式!

回答

1

兩臺機器都有相同的Java語言環境(Locale.getDefault()) - >我已經試過了。

這是默認字符集,而不是缺省語言環境,它決定了在解碼/編碼沒有指定字符集的字符串時使用的字符集。

檢查您的Windows和Linux計算機上返回的內容Charset.defaultCharset().name()。根據你所報告的症狀,我預計他們會有所不同。

+0

是的,謝謝你,這暗示是在正確的方向。 Windows機器使用Windows-1252,而Linux使用UTF-8。 – karlis

+0

使用String s3 = new String(「grün」.getBytes(「windows-1252」),「UTF-8」);訣竅,現在它在Linux機器上也是正確的。然而,我並不是爲什麼我必須在Linux上使用windows charset,也許這個字符串最初是在Windows機器上創建的...... – karlis

+0

*「...也許該字符串最初是在Windows機器上創建的。」*可能是! –

1

像這樣的東西是無效的:

String s3 = new String("grün".getBytes(), "UTF-8"); 

這裏發生:您可以使用您在運行此係統的默認字符編碼得到字節的字符串"grün"(因爲你沒有指定在getBytes()的調用中進行編碼),然後將這些字節轉換回String,指定這些字節爲UTF-8編碼的文本:

characters =>缺省字符編碼中的字節(可能是也可能不是UTF -8)=>轉換回字符,就好像字節是UT F-8編碼文本

這顯然只有在系統的默認字符編碼是UTF-8時才能正常工作。在Windows上它不是(它可能是Windows-1252)。

字符串本身沒有character encoding。沒有「UTF-8字符串」或「將字符串從X轉換爲UTF-8」之類的東西。字符編碼指定字符串中的字符如何轉換爲字節,反之亦然,但不是字符串本身的屬性。您可以可以有一個字節數組,代表以特定字符編碼編碼的文本。 (就像「十進制」和「十六進制」不是數字本身的屬性,只是如何表示數字)。

不要以這樣的方式編寫程序,它取決於它所運行的系統的默認字符編碼;這意味着,例如,不要在String上調用getBytes(),而不指定字符編碼(例如,如果未指定,則還有其他使用默認編碼的API調用)。

+0

謝謝!你是對的,不應該這樣使用。然而,在找到真正的問題和解決方案之後,改進總是可能的。 – karlis

+0

是的,所以解決方案是:檢查程序中是否依賴默認字符編碼的地方,並修復這些地方,使其不符合。 – Jesper

+0

這是我必須使用這樣的東西的唯一部分。並感謝你的答案,現在它應該做它應該做的。 – karlis