我正在用Netty实现基于TCP协议的TimeEcho服务:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//这里已经在pipeline中定义了StringDecoder,所以msg已被解码为String
String command = (String) msg;
System.out.println("get command:"+command);
String echoMsg = command.equalsIgnoreCase("QUERY TIME")?new Date(System.currentTimeMillis()).toString():"查询失败";
echoMsg=echoMsg+System.getProperty("line.separator");
System.out.println("print sys time!"+echoMsg);
ByteBuf resp = Unpooled.copiedBuffer(echoMsg);
ctx.writeAndFlush(resp);
}
遇到的问题:
上面的代码运行在windows平台,由于window默认GBK编码,在本地用UTF-8接收时会产生乱码,我需要改变echoMsg发送回来的编码变为UTF-8。
将上面的
ByteBuf resp = Unpooled.copiedBuffer(echoMsg);
改为
ByteBuf resp = Unpooled.copiedBuffer(echoMsg.getBytes("UTF-8"));
就将返回的字符串编码设置为了UTF-8(不设置默认为GBK),正常显示。
收获:
- 在JVM中,字符都是以Unicode编码的,只有从外界读取或者写出到外界时才会涉及编码的问题!
- getBytes(),经过查看源码,它是调用了StringCoding.encode(Charset charset)方法,把unicode字符串以“charset”字符集编码成字符数组并保存(如果未指定参数则默认为系统默认编码),并且可能相同的字符串以不同字符集编码后产生的数组长度可能会不同。
- new String(array,charset)则是将被编码过的array数组按照charset编码方式进行解码,必须要保证charset与array的实际编码格式正确对应才能保证完全正确解码。