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

来源:互联网 发布:淘宝刷钻怎么刷 编辑:程序博客网 时间:2024/05/01 03:27

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

先看怎么编码。

?
ObjectEncoder.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Override
    protectedObject encode(ChannelHandlerContext ctx, Channel channel, Object msg) throwsException {
        ChannelBufferOutputStream bout =
            newChannelBufferOutputStream(dynamicBuffer(
                    estimatedLength, ctx.getChannel().getConfig().getBufferFactory()));
        bout.write(LENGTH_PLACEHOLDER);
        ObjectOutputStream oout = newCompactObjectOutputStream(bout);
        oout.writeObject(msg);
        oout.flush();
        oout.close();
 
        ChannelBuffer encoded = bout.buffer();
        encoded.setInt(0, encoded.writerIndex() - 4);
        returnencoded;
    }

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

?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
 * Object编码类
 *
 * @author lihzh
 * @alia OneCoder
 * @blog http://www.coderli.com
 */
publicclass MyObjEncoder implementsChannelDownstreamHandler {
 
    @Override
    publicvoid handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
            throwsException {
        // 处理收发信息的情形
        if(e instanceofMessageEvent) {
            MessageEvent mEvent = (MessageEvent) e;
            Object obj = mEvent.getMessage();
            if(!(obj instanceofCommand)) {
                ctx.sendDownstream(e);
                return;
            }
            ByteArrayOutputStream out = newByteArrayOutputStream();
            ObjectOutputStream oos = newObjectOutputStream(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);
        }
    }
}
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * Object解码类
 *
 * @author lihzh
 * @alia OneCoder
 * @blog http://www.coderli.com
 */
publicclass MyObjDecoder implementsChannelUpstreamHandler {
 
    @Override
    publicvoid handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
            throwsException {
        if(e instanceofMessageEvent) {
            MessageEvent mEvent = (MessageEvent) e;
            if(!(mEvent.getMessage() instanceofChannelBuffer)) {
                ctx.sendUpstream(mEvent);
                return;
            }
            ChannelBuffer buffer = (ChannelBuffer) mEvent.getMessage();
            ByteArrayInputStream input = newByteArrayInputStream(buffer.array());
            ObjectInputStream ois = newObjectInputStream(input);
            Object obj = ois.readObject();
            Channels.fireMessageReceived(e.getChannel(), obj);
        }
    }
}

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

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

如非特别注明,本站内容均为OneCoder原创,转载请务必注明作者和原始出处。
本文地址:http://www.coderli.com/netty-custom-object-codec

0 0