Dojo cometdチャネルを使用して任意のXMLEncodedJavaオブジェクトを前後にプッシュしたいのですが、ペイロードを正しくデコードするのに問題があります。
これを行うために、チャットルームクライアントのデモンストレーションプログラムの簡略版にこのsendメソッドがあります。
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(">",">").replaceAll("<", "<").replaceAll("&","&");
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 = <?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_16" class="java.beans.XMLDecoder">
<object class="java.util.HashMap">
<void method="put">
<string>intArray</string>
<array class="int" length="1">
<void index="0">
<int>1</int>
</void>
</array>
</void>
</object>
</java>
>> decoded payload={intArray=[I@2f1e75}, class=class java.util.HashMap
リバーシブルです。XMLEncoded /XMLDecodedである文字列オブジェクト内にこれらの文字を配置するという私の実験は良くありませんでした-それらは二重に保護されていませんでした-それで私の野蛮なデコードもそれらに影響を与えました。
問題は、これらの文字列をデコードする適切な方法は何ですか?迅速で汚いコードの代わりに使用する必要のあるJSONライブラリはありますか?cometdのJavaクライアントライブラリでエラーが発生した可能性がありますか?
(注:この実験ではcometd-1.0.0rc0ライブラリを使用しています)。
編集:通信は、cometd通信を処理すると思っていたものとは同じWebサーバー内の別のデプロイメントを介して行われ、そのデプロイメントにはXML保護を行うfilter.jsonが含まれていることが判明しました。
http://groups.google.com/group/cometd-users/browse_thread/thread/6fbdaae669e5f9d3
言い換えれば、私のコード外の構成の問題です。うまくいけば、改訂された展開がこの問題を解決するでしょう。