Java NotSerializableException с пользовательским пакетом данных - PullRequest
0 голосов
/ 24 апреля 2018

В настоящее время я работаю над простой структурой сервер-клиент для будущих проектов. Я решил, что будет лучше создать свой собственный пакет данных с пользовательской информацией заголовка, такой как локальный / публичный 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;
    }

}

(я убрал геттеры и сеттеры)

Я решил использовать объект, чтобы я мог отправить что-нибудь в классе. Он хорошо компилируется, но если я пытаюсь отправить простую строку, упакованную в классе, я получаю NotSerializableException. Существуют ли какие-либо атрибуты или поля, которые нельзя преобразовать в поток, или я должен изменить класс на общий? Я НЕ эксперт в области потоков и сетей, поэтому я благодарен за каждую помощь и объяснения, которые я могу получить.

ПРИМЕЧАНИЕ: я не являюсь носителем английского языка, прошу прощения за любые орфографические / грамматические проблемы.

Ответы [ 3 ]

0 голосов
/ 24 апреля 2018

Вы должны реализовать интерфейс Serializable для передачи класса по сети.

Измените первую строку вашего класса на:

import java.io.Serializable;
public class DataPackage implements Serializable{
0 голосов
/ 24 апреля 2018

Ваш класс должен реализовывать интерфейс Serializable .

Также обратите внимание, что каждое свойство вашего класса, в вашем случае объект также должно реализовывать этот интерфейс для правильной работы сериализации.

Так что я хотел бы рассмотреть возможность сделать этот класс универсальным, чтобы заставить объект реализовать интерфейс Serializable.

РЕДАКТИРОВАТЬ: например, если вы попытаетесь сериализовать DataPackage, который содержит ByteBuffer (который не Serializable), как это: 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;
        }

    }
0 голосов
/ 24 апреля 2018

java.io.NotSerializableException генерируется, когда ваш объект не сериализуем, что означает, что ваше object или любое свойство non-transient этого объекта не реализует интерфейс Serializable. И в вашем случае, DataPackage не Serializable. Serializable - это маркер interface, который в основном говорит JVM, что любой instance типа Serializable может быть сериализован. Здесь вы можете просмотреть документы Сериализуемый и NotSerializableException .

...