很简单的一段代码服务端(java代码):
public void TestPushMessage()
{
String msg = "pushlet test message中文为什么不行"; //前面是英文 后面的中文会无法发送
Event event = Event.createDataEvent("Alarm"); //创建一个Alarm频道事件
event.setField("msg", msg);//把msg打包进去
Dispatcher.getInstance().multicast(event);//直接发送
}
客户端(js代码):
function htmInit()
{
try{
PL._init() ;
PL.joinListen("Alarm");//加入一个主题(告警)
}catch(e) { alert(e.message) ; }
}
function onData(event)
{
var msg = event.get("msg");
alert(msg);
}
</script>
测试后会发现,如果发送的内容全是英文都OK,不会有异常现象,但是中文死活不行(开发环境是Tomcat7+myeclipse10)。网络上找到一个解决方案:http://witcheryne.iteye.com/blog/1010797。说在ul.justobjects.pushlet.core.Event中找到 toQueryString() 方法, 添加ISO-8859-1 to UTF-8的转换代码,试了下不起作用。用Winsock Expert抓包发现发送的消息,格式是XML的,所以修改toQueryString不起作用理所当然的了。还有就是抓包发现返回的字符串“pushlet test message中文为什么不行”只看到了前面的“pushlet test message”,都没有中文,而且连XML的结束标志"</pushlet>"也没看到,反正就是不完整的xml片段,猜测是在输出的过程中发生了异常。
经过好长时间的调试,最终发现不能输出中文的原因。在XMLAdapter.java文件的push()方法中,
public void push(Event anEvent) throws IOException {
debug("event=" + anEvent);
// Send the event as XML to the client and flush.
out.print(anEvent.toXML(strictXML));
out.flush();
}
out是ServletOutputStream类实例,在调用print方法时,里面的字符串参数如果含有中文就可能会产生异常,应该换用PrintWriter,这个可以参考《Tomcat6+proxool 中文不能正常显示解决方案》:http://www.chendw.cn/problemsolving/177.html。于是将XMLAdapter.java修改如下:
// Copyright (c) 2000 Just Objects B.V. <just@justobjects.nl>
// Distributable under LGPL license. See terms of license at gnu.org.
package nl.justobjects.pushlet.core;
import nl.justobjects.pushlet.util.Log;
//import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* ClientAdapter that sends Events as XML.
*
* @author Just van den Broecke - Just Objects ©
* @version $Id: XMLAdapter.java,v 1.7 2007/11/09 13:15:35 justb Exp $
*/
class XMLAdapter implements ClientAdapter {
/**
* Header for strict XML
*/
// public static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
private String contentType = "text/plain;charset=UTF-8";
//private ServletOutputStream out = null;
private PrintWriter pw = null ;
private HttpServletResponse servletRsp;
private boolean strictXML;
/**
* Initialize.
*/
public XMLAdapter(HttpServletResponse aServletResponse) {
this(aServletResponse, false);
}
/**
* Initialize.
*/
public XMLAdapter(HttpServletResponse aServletResponse, boolean useStrictXML) {
servletRsp = aServletResponse;
// Strict XML implies returning a complete XML document
strictXML = useStrictXML;
if (strictXML) {
contentType = "text/xml;charset=UTF-8";
}
}
public void start() throws IOException {
// If content type is plain text
// then this is not a complete XML document, but rather
// a stream of XML documents where each document is
// an Event. In strict XML mode a complete document is returned.
servletRsp.setContentType(contentType);
pw = servletRsp.getWriter();
// Don't need this further
servletRsp = null;
// Start XML document if strict XML mode
if (strictXML) {
pw.print("<pushlet>");
}
}
/**
* Force client to refresh the request.
*/
public void push(Event anEvent) throws IOException {
debug("event=" + anEvent);
// Send the event as XML to the client and flush.
pw.print(anEvent.toXML(strictXML));
pw.flush();
}
/**
* No action.
*/
public void stop() throws IOException {
// Close XML document if strict XML mode
if (strictXML) {
pw.print("</pushlet>");
pw.flush();
}
}
private void debug(String s) {
Log.debug("[XMLAdapter]" + s);
}
}
至此,不能输出汉字的问题解决了(SerialzedAdapter类估计也要改?ObjectOutputStream新手没研究过这个类。^_^)