1

我目前正在为未来的项目开发一个简单的服务器 - 客户端结构。我决定最好使用自定义标头信息(例如本地/公共 ip、时间戳等)创建自己的数据包。以下是我想出的类:

public class DataPackage {
    private Object object;
    private Date time;
    private long timeMs;
    private boolean responded;
    private String publicIp;
    private String internalIp;
    private int hash;

    public DataPackage(Object object) {
        this.object = object;
        this.responded = false;
        this.time = Calendar.getInstance().getTime();
        this.timeMs = System.currentTimeMillis();
        this.publicIp = this.generatePublicIp();
        this.internalIp = this.generateInternalIp();
        this.hash = System.identityHashCode(this);
    }

    private String generatePublicIp() {
        try {
            URL whatismyip = new URL("http://checkip.amazonaws.com");
            BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));

            return in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String generateInternalIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

}

(我删除了 getter 和 setter)

我决定使用一个对象,这样我就可以在课堂上发送任何东西。它编译得很好,但是如果我尝试发送一个简单的字符串,打包在类中,我会得到一个 NotSerializableException。是否有任何属性或字段无法转换为流,或者我应该将类更改为通用类?我不是流和网络方面的专家,所以我很感谢我能得到的每一点帮助和解释。

注意:我不是以英语为母语的人,请原谅任何拼写/语法问题。

4

3 回答 3

1

您应该实现 Serializable 接口,以便通过网络传输类。

将班级的第一行更改为:

import java.io.Serializable;
public class DataPackage implements Serializable{
于 2018-04-24T15:59:09.267 回答
0

你的类应该实现Serializable接口。

另请注意,您的类的每个属性,在您的案例中,对象也应该实现此接口,以便序列化正常工作。

所以我会考虑使这个类通用以强制对象实现 Serializable 接口。

编辑:例如,如果您尝试像这样序列化包含 ByteBuffer(不可序列化)的 DataPackage:,new DataPackage(ByteBuffer.allocate(1))您将收到异常。

尝试这个 :

    import java.io.Serializable;

    public class DataPackage<T extends Serializable> implements Serializable{
    private T object;
    private Date time;
    private long timeMs;
    private boolean responded;
    private String publicIp;
    private String internalIp;
    private int hash;

    public DataPackage(T object) {
        this.object = object;
        this.responded = false;
        this.time = Calendar.getInstance().getTime();
        this.timeMs = System.currentTimeMillis();
        this.publicIp = this.generatePublicIp();
        this.internalIp = this.generateInternalIp();
        this.hash = System.identityHashCode(this);
    }

    private String generatePublicIp() {
        try {
            URL whatismyip = new URL("http://checkip.amazonaws.com");
            BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));

            return in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String generateInternalIp() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

}

通过这种方式,您可以确保您尝试发送的对象都是可序列化的。

如果您不想使用泛型而不是像这样制作Serializable 类型的对象

import java.io.Serializable;

        public class DataPackage implements Serializable{
        private Serializable object;
        private Date time;
        private long timeMs;
        private boolean responded;
        private String publicIp;
        private String internalIp;
        private int hash;

        public DataPackage(Serializable object) {
            this.object = object;
            this.responded = false;
            this.time = Calendar.getInstance().getTime();
            this.timeMs = System.currentTimeMillis();
            this.publicIp = this.generatePublicIp();
            this.internalIp = this.generateInternalIp();
            this.hash = System.identityHashCode(this);
        }

        private String generatePublicIp() {
            try {
                URL whatismyip = new URL("http://checkip.amazonaws.com");
                BufferedReader in = new BufferedReader(new InputStreamReader(whatismyip.openStream()));

                return in.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        private String generateInternalIp() {
            try {
                return InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

    }
于 2018-04-24T16:46:23.377 回答
0

java.io.NotSerializableException当您的对象不可序列化时抛出,这意味着您object或该对象的任何non-transient属性都没有实现Serializable接口。在您的情况下,DataPackage它是不可序列化的。Serializable是一个标记,interface 它基本上告诉JVM任何类型都可以序列化。在这里,您可以浏览SerializableNotSerializableException的文档。instanceSerializable

于 2018-04-24T15:49:47.117 回答