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

}

(Я удалил геттеры и сеттеры)

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

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

3 ответа

Решение

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

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

import java.io.Serializable;
public class DataPackage implements Serializable{

Ваш класс должен реализовывать интерфейс 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;
        }

    }

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

Другие вопросы по тегам