0

我想使用 Dojo cometd 通道来回推送任意 XMLEncoded java 对象,但我在正确解码有效负载时遇到了问题。

为了做到这一点,我在聊天室客户端演示程序的精简版中有这个发送方法:

private void send(String string) {
  Map<String, Object> map = new HashMap<String, Object>();
  map.put("intArray", new int[] {1});

  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  XMLEncoder xmlEncoder = new XMLEncoder(baos);
  xmlEncoder.writeObject(map);
  xmlEncoder.close();
  Map<String, Object> encodedMap = new HashMap<String, Object>();
  try {
    String encoded = baos.toString("UTF-8");
    encodedMap.put("xmlpayload", encoded);
  } catch (Exception e) {
   throw new RuntimeException("could not use UTF-8", e);
  } 
  bayreuxClient.publish("/prototype/a", encodedMap, String.valueOf(System.currentTimeMillis()));
}

现在它创建了一个扁平化为 UTF-8 编码字节流的 XML 片段(我知道我也需要处理编码,但这不是现在的问题)。

接受此消息的消息侦听器如下所示:

listener = new MessageListener() {
  @Override
  public void deliver(Client fromClient, Client toClient, Message msg) {
    if (!_connected) {
      _connected = true;
      synchronized (this) {
      this.notify();
    }
  }
  Object data = msg.getData();
  if (data instanceof Map) {
    Map map = (Map) data;
    Object rawPayload = map.get("xmlpayload");
    if (rawPayload instanceof String) {
      System.out.println("xmlpayload = " + rawPayload);
      ByteArrayInputStream bais;
      try {
        String xmlPayload = ((String) rawPayload).replaceAll("&gt;",">").replaceAll("&lt;", "<").replaceAll("&amp;","&");
        bais = new ByteArrayInputStream(xmlPayload.getBytes("UTF-8"));
        XMLDecoder xmlDecoder = new XMLDecoder(bais);
        Object o = xmlDecoder.readObject();
        xmlDecoder.close();
        System.out.println(">> decoded payload=" + o + ", class=" + o.getClass());
      } catch (UnsupportedEncodingException e) {
        throw new RuntimeException("no UTF-8", e);
      }
     }
   }
  }
 };
 address = new Address("localhost", 8080);
 bayreuxClient = new BayeuxClient(httpClient, address, "/cometd/cometd");
 bayreuxClient.addListener(listener);

正如您所看到的,我通过反复试验发现,发送的字符串具有小于、大于和与号字符的保护,然后我取消保护并调用 XMLDecode。

输出是:

xmlpayload = &lt;?xml version="1.0" encoding="UTF-8"?&gt; 
&lt;java version="1.6.0_16" class="java.beans.XMLDecoder"&gt; 
 &lt;object class="java.util.HashMap"&gt; 
  &lt;void method="put"&gt; 
   &lt;string&gt;intArray&lt;/string&gt; 
   &lt;array class="int" length="1"&gt; 
    &lt;void index="0"&gt; 
     &lt;int&gt;1&lt;/int&gt; 
    &lt;/void&gt; 
   &lt;/array&gt; 
  &lt;/void&gt; 
 &lt;/object&gt; 
&lt;/java&gt; 

>> decoded payload={intArray=[I@2f1e75}, class=class java.util.HashMap

所以它是可逆的。我将这些字符放在被 XMLEncoded/XMLDecoded 的字符串对象中的实验并不好——它们没有受到双重保护——所以我的粗暴解码也影响了它们。

问题是:解码这些字符串的正确方法是什么?我需要使用 JSON 库来代替我快速而肮脏的代码吗?可能我在 Cometd 的 Java 客户端库中遇到了错误?

(注意:我在这个实验中一直使用 cometd-1.0.0rc0 库)。


编辑:事实证明,通信是通过同一网络服务器中的另一个部署发生的,而不是我认为负责 cometd 通信的部署,并且部署包含进行 XML 保护的 filter.json。

http://groups.google.com/group/cometd-users/browse_thread/thread/6fbdaae669e5f9d3

换句话说,我的代码之外的配置问题。希望修改后的部署能够解决这个问题。

4

1 回答 1

0

用于对 XML 进行转义的最佳库是 Apache Commons Lang,

   StringEscapeUtils.unescapeXml();

看起来这是您使用的 Bayeux Java 客户端中的一个错误。它的编码/解码不是对称的。我打算用它。现在我会三思而后行:)

于 2009-09-28T15:28:26.473 回答