带有自定义DataPackage

时间:2018-04-24 15:40:29

标签: java exception serialization stream notserializableexception

我目前正致力于一个简单的服务器 - 未来项目的客户端结构。我决定最好使用自定义标头信息创建自己的数据包,例如本地/公共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。是否有任何属性或字段无法转换为流或我应该将类更改为通用?我不是流媒体和网络方面的专家,所以我非常感谢我能得到的每一点帮助和解释。

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

3 个答案:

答案 0 :(得分:1)

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

将班级的第一行改为:

WITH company_size(comp_id, employee_count, total_salries) AS (
  SELECT comp_id
       , count(*)
       , sum(pay_rate)
    FROM position NATURAL JOIN works
   GROUP BY comp_id
)
SELECT comp_id
     , employee_count
     , total_salaries
  FROM company_size
 WHERE employee_count = (SELECT max(employee_count) 
                           FROM company_size);

答案 1 :(得分:0)

当您的对象不可序列化时,抛出

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

答案 2 :(得分:0)

您的课程应该实现Serializable界面。

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

所以我会考虑使这个类通用,以强制对象实现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类型的 object ,请执行以下操作:

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;
        }

    }