2013-06-04 75 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是欧元字符。