2013-06-04 78 views
1

我在調試將二進制消息轉換爲XML Web服務的第三方網關係統。當它接收到包含特殊字符0x80,0x81,0x82和0x83的消息時,它們不會以XML格式正確發送。在XML中發送非標準字符

我已經將問題縮小到了將byte []轉換爲String的位置,併產生了一個錯誤示例。特殊值全部轉化爲相同的「未知」字符。

public static void main(String[] args) { 
    test(0x80);test(0x81);test(0x82);test(0x83); 
} 
public static void test(int value) { 
    String message = new String(new byte[]{(byte)value}); 
    System.out.println(value + " => " + message + " => " + Arrays.toString(message.getBytes())); 
} 

輸出

128 => � => [-17, -65, -67] 
129 => � => [-17, -65, -67] 
130 => � => [-17, -65, -67] 
131 => � => [-17, -65, -67] 

我不知道應如何解決。我試着更改他們的代碼以使用明確的字符集

new String(bytes, Charset.forName("UTF-8")) 

但是,這會導致同樣的問題。值0x80-0x83似乎不存在有效的XML entities

我發現你可以使用字符構造函數哪種工作,但翻譯下面,我不知道是否正確?

new String(new char[]{(char) value}, 0, 1); 

輸出

128 => weird box character 0080 => [-62, -128] 
129 => weird box character 0081 => [-62, -127] 
130 => weird box character 0082 => [-62, -126] 
131 => weird box character 0083 => [-62, -125] 

回答

1

不能直接在XML文檔中傳輸二進制數據 - 有是有,例如一個ASCII零沒有有效的辦法。

您需要將其編碼爲ASCII字符串(base64或類似的)並傳輸該字符串,然後在接收端將其解碼。

+0

它不一定是ASCII字符串,而是*文本*字符串,採用約定的編碼(在XML上下文中通常是UTF-8)。 –

+0

然後,您可能需要重新說明有關「二進制消息」的部分。 –

0

首先,使用

String message = new String(new byte[]{(byte)value}); 

幾乎總是錯的。要將byte[]轉換爲String,您必須決定使用哪種字符編碼。上面的代碼將(不幸)使用JVM默認編碼進行轉換,這取決於各種操作系統設置(如果用戶更改這些設置,可能會隨時更改)。在幾乎所有情況下,您都想明確指定編碼。

我們您的問題:

我不知道應如何解決。我試圖改變他們的代碼 使用顯式的字符集

new String(bytes, Charset.forName("UTF-8"))

然而這會導致同樣的問題。

這是正常現象。您告訴Java將單字節序列「0x80」解釋爲UTF-8。但是,這不是有效的UTF-8字符串。因此Java使用Unicode replacement character來指示錯誤。

爲了解決這個問題,你必須找出什麼「0x80」等意思是在你得到的數據。找出哪些字符編碼數據使用,並使用該編碼轉換爲String


作爲猜測:數據可能使用Windows編碼CP 1252(通常與ISO 8859-1混合使用)。在CP 1252中,0x80是歐元字符。