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

来源:互联网 发布:云脉文档识别破解 知乎 编辑:程序博客网 时间:2024/04/29 22:38

看到题目,有的同学可能会想,上回不是说过对象传递了吗?是的,只是在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中的应用而已。

0 0