• 热门专题

Java NIO框架Netty教程(九) Object对象编/解码

作者:OneCoder  发布日期:2012-07-25 10:52:20
Tag标签:NIO框架  Netty教程  Object对象  
  • 看到题目,有的同学可能会想,上回不是说过对象传递了吗?是的,只是在Java NIO框架Netty教程(八) Object对象传递 中,我们只是介绍如何使用Netty提供的编/解码工具,完成对象的序列化。这节是想告诉你Netty具体是怎么做的,也许有的同学想自己完成序列化呢?况且,对象的序列化,随处可用:)

    先看怎么编码。


    @Override
        protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
            ChannelBufferOutputStream bout =
                new ChannelBufferOutputStream(dynamicBuffer(
                        estimatedLength, ctx.getChannel().getConfig().getBufferFactory()));
            bout.write(LENGTH_PLACEHOLDER);
            ObjectOutputStream oout = new CompactObjectOutputStream(bout);
            oout.writeObject(msg);
            oout.flush();
            oout.close();
    
            ChannelBuffer encoded = bout.buffer();
            encoded.setInt(0, encoded.writerIndex() - 4);
            return encoded;
        }
    
    

    其实你早已经应该想到了,在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对象序列化的细节问题,不在文本讨论的范围内,不过不知您是否感兴趣试试自己写一个呢?所谓,多动手嘛。

     

    /**
     * Object编码类
     * 
     * @author lihzh
     * @alia OneCoder
     * @blog http://www.it165.net
     */
    public class MyObjEncoder implements ChannelDownstreamHandler {
    
    	@Override
    	public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
    			throws Exception {
    		// 处理收发信息的情形
    		if (e instanceof MessageEvent) {
    			MessageEvent mEvent = (MessageEvent) e;
    			Object obj = mEvent.getMessage();
    			if (!(obj instanceof Command)) {
    				ctx.sendDownstream(e);
    				return;
    			}
    			ByteArrayOutputStream out = new ByteArrayOutputStream();
    			ObjectOutputStream oos = new ObjectOutputStream(out);
    			oos.writeObject(obj);
    			oos.flush();
    			oos.close();
    			ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
    			buffer.writeBytes(out.toByteArray());
    			e.getChannel().write(buffer);
    		} else {
    			// 其他事件,自动流转。比如,bind,connected
    			ctx.sendDownstream(e);
    		}
    	}
    }
    /**
     * Object解码类
     * 
     * @author lihzh
     * @alia OneCoder
     * @blog http://www.it165.net
     */
    public class MyObjDecoder implements ChannelUpstreamHandler {
    
    	@Override
    	public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
    			throws Exception {
    		if (e instanceof MessageEvent) {
    			MessageEvent mEvent = (MessageEvent) e;
    			if (!(mEvent.getMessage() instanceof ChannelBuffer)) {
    				ctx.sendUpstream(mEvent);
    				return;
    			}
    			ChannelBuffer buffer = (ChannelBuffer) mEvent.getMessage();
    			ByteArrayInputStream input = new ByteArrayInputStream(buffer.array());
    			ObjectInputStream ois = new ObjectInputStream(input);
    			Object obj = ois.readObject();
    			Channels.fireMessageReceived(e.getChannel(), obj);
    		}
    	}
    }
    

    怎么样,是不是也好用?所谓,模仿,学以致用。

    不过,提醒一下大家,这个实现里有很多硬编码的东西,切勿模仿,只是为了展示Object,编解码的处理方式和在Netty中的应用而已。

    下一篇:Java NIO框架Netty教程(十) Object对象的连续收发解析分析       http://www.it165.net/pro/html/201207/3352.html

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规