日期:2014-05-20  浏览次数:20894 次

MINA中传输序列化对象的问题
近期在用MINA搭建一个网络程序,需要直接传递对象。
比如说我要传输下面这个类的对象:
Java code
public class TestSeri implements Serializable{
    
    /**
     * 
     */
    private static final long serialVersionUID = 4L;
    
    int i = 0;
    IoBuffer buffer =  null;
    
    public TestSeri(IoBuffer buffer)
    {
        this.buffer = buffer;
    }
}

然后我这样传输:
Java code
String s = "I am coming";
        IoBuffer buffer = IoBuffer.allocate(1024);
        buffer.putString(s, Charset.forName("UTF-8").newEncoder());
        buffer.flip();
        TestSeri ts = new TestSeri(buffer);
        session.write(ts);

session.write就是发送这个对象到远程服务器上,但是每次都报错:
org.apache.mina.filter.codec.ProtocolEncoderException: org.apache.mina.common.BufferDataException: java.io.NotSerializableException: org.apache.mina.common.SimpleBufferAllocator$SimpleBuffer

如果我把TestSeri里的IoBuffer去掉,那么可以正常发送,但只要加上IoBuffer,就无法发送。
JAVA中,要网络传输一个对象,需要实现序列化接口。而且不仅你传输的对象要实现序列化接口,这个对象里面包含的别的对象也要实现序列化接口,因此看起来错误的原因是IoBuffer或IoBuffer里面的对象没有实现序列化接口。可是如果我直接发送一个IoBuffer
session.write(buffer);
它却不报序列化错误,因此IoBuffer又应该是已经被序列化的。

苦思无解,大牛现身吧。

------解决方案--------------------
Java对象的序列化,和IoBuffer里面的数据,不是一个概念。

一个类的对象,进行序列化以后的数据,是具有一定数据格式的。
而,IoBuffer里面的数据,则未必遵循Java对象的序列化规则,
因为,你在IoBuffer里面未必保存的是Java对象序列化后的结果。

楼主创建这个类,让人很纠结。

mina框架的目的,就是隔离功能,简化开发。
可是,楼主没有将功能隔离开。
楼主的对象,只保存业务方面的信息,不保存二进制数据。
二进制数据,是Java对象编码(序列化)以后的结果。

Mina框架,总体上来说,就是IoService、IoProcessor、IoFilter和IoHandler这四个部分。
网络数据和Java对象的相互转换,这个功能,使用IoFilter来实现。
那么,CodecIoFilter中,只应该存在要传输的Java对象,以及IoBuffer对象。
待传输的Java对象,是纯粹的JavaBean,不应该是那种二不像的东西。

最后,Java对象的序列化,可以参考DataOutputStream/DataInputStream等等。
NIO中对应序列化的对象,目前,我还没去找过,上面那两个,在阻塞IO中经常会用到。