1. 程式人生 > >Java NIO框架Netty教程(九) Object對象編/解碼

Java NIO框架Netty教程(九) Object對象編/解碼

log writer arr num context 不兼容 是的 pat .html

看到題目,有的同學可能會想,上回不是說過對象傳遞了嗎?是的,只是在Java NIO框架Netty教程(八) Object對象傳遞中,我們只是介紹如何使用Netty提供的編/解碼工具,完成對象的序列化。這節是想告訴你Netty具體是怎麽做的,也許有的同學想自己完成序列化呢?況且,對象的序列化,隨處可用:)

先看怎麽編碼。

view sourceprint? 01.@Override 02.protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { 03.
ChannelBufferOutputStream bout = 04.new ChannelBufferOutputStream(dynamicBuffer( 05.estimatedLength, ctx.getChannel().getConfig().getBufferFactory())); 06.bout.write(LENGTH_PLACEHOLDER); 07.ObjectOutputStream oout = new CompactObjectOutputStream(bout); 08.oout.writeObject(msg); 09.oout.flush(); 10.oout.close();
11. 12.ChannelBuffer encoded = bout.buffer(); 13.encoded.setInt(0, encoded.writerIndex() - 4); 14.return encoded; 15.}

其實你早已經應該想到了,在Java中對對象的序列化自然跑不出ObjectOutputStream了。Netty這裏只是又做了一層包裝,在流的開頭增加了一個4字節的標誌位。所以,Netty聲明,該編碼和解碼的類必須配套使用,與單純的ObjectIntputStream不兼容。

* An encoder which serializes a Java object into a {@link ChannelBuffer}.
* <p>
* Please note that the serialized form this encoder produces is not
* compatible with the standard {@link ObjectInputStream}. Please use
* {@link ObjectDecoder} or {@link ObjectDecoderInputStream} to ensure the
* interoperability with this encoder.

解碼自然是先解析出多余的4位,然後再通過ObjectInputStream解析。

關於Java對象序列化的細節問題,不在文本討論的範圍內,不過不知您是否感興趣試試自己寫一個呢?所謂,多動手嘛。

view sourceprint? 01./** 02.* Object編碼類 03.* 04.* @author lihzh 05.* @alia OneCoder 06.* @blog http://www.it165.net 07.*/ 08.public class MyObjEncoder implements ChannelDownstreamHandler { 09. 10.@Override 11.public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) 12.throws Exception { 13.// 處理收發信息的情形 14.if (e instanceof MessageEvent) { 15.MessageEvent mEvent = (MessageEvent) e; 16.Object obj = mEvent.getMessage(); 17.if (!(obj instanceof Command)) { 18.ctx.sendDownstream(e); 19.return; 20.} 21.ByteArrayOutputStream out = new ByteArrayOutputStream(); 22.ObjectOutputStream oos = new ObjectOutputStream(out); 23.oos.writeObject(obj); 24.oos.flush(); 25.oos.close(); 26.ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); 27.buffer.writeBytes(out.toByteArray()); 28.e.getChannel().write(buffer); 29.} else { 30.// 其他事件,自動流轉。比如,bind,connected 31.ctx.sendDownstream(e); 32.} 33.} 34.} 35./** 36.* Object解碼類 37.* 38.* @author lihzh 39.* @alia OneCoder 40.* @blog http://www.it165.net 41.*/ 42.public class MyObjDecoder implements ChannelUpstreamHandler { 43. 44.@Override 45.public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) 46.throws Exception { 47.if (e instanceof MessageEvent) { 48.MessageEvent mEvent = (MessageEvent) e; 49.if (!(mEvent.getMessage() instanceof ChannelBuffer)) { 50.ctx.sendUpstream(mEvent); 51.return; 52.} 53.ChannelBuffer buffer = (ChannelBuffer) mEvent.getMessage(); 54.ByteArrayInputStream input = new ByteArrayInputStream(buffer.array()); 55.ObjectInputStream ois = new ObjectInputStream(input); 56.Object obj = ois.readObject(); 57.Channels.fireMessageReceived(e.getChannel(), obj); 58.} 59.} 60.}

怎麽樣,是不是也好用?所謂,模仿,學以致用。

不過,提醒一下大家,這個實現裏有很多硬編碼的東西,切勿模仿,只是為了展示Object,編解碼的處理方式和在Netty中的應用而已。

Java NIO框架Netty教程(九) Object對象編/解碼