Java 带有自定义数据包的 NotSerializableException
Java NotSerializableException with custom DataPackage
我目前正在为未来的项目开发一个简单的服务器-客户端结构。我决定最好用自定义 header-information 创建自己的 data-package,例如 local/public ip、时间戳等。以下是我想出的 class :
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)
我决定使用 object,这样我就可以在 class 中发送任何内容。它编译得很好,但如果我尝试发送一个简单的字符串,打包在 class 中,我会得到一个 NotSerializableException。是否有任何属性或字段无法转换为流,或者我应该将 class 更改为通用的?我不是流和网络方面的专家,所以我非常感谢我能得到的每一点帮助和解释。
注意:我不是以英语为母语的人,如有任何 spelling/grammar 问题,请原谅。
当您的对象不可序列化时抛出 java.io.NotSerializableException
,这意味着您的 object
或该对象的任何 non-transient
属性 未实现 Serializable
界面。在您的情况下, DataPackage
不是可序列化的。 Serializable
是一个标记 interface
,它基本上告诉 JVM
Serializable
类型的任何 instance
都可以序列化。在这里您可以浏览 Serializable and NotSerializableException.
的文档
您应该实现 Serializable 接口,以便 class 通过网络传输。
将 class 的第一行更改为:
import java.io.Serializable;
public class DataPackage implements Serializable{
您的 class 应该实现 Serializable 接口。
另请注意,您的 class 的每个 属性,在您的情况下 object 也应实现此接口,以便序列化正常工作。
所以我会考虑使这个 class 通用以强制对象实现 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;
}
}
通过这种方式,您可以确保您尝试发送的对象都是可序列化的。
如果你不想使用泛型,那么像这样制作可序列化类型的 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;
}
}
我目前正在为未来的项目开发一个简单的服务器-客户端结构。我决定最好用自定义 header-information 创建自己的 data-package,例如 local/public ip、时间戳等。以下是我想出的 class :
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)
我决定使用 object,这样我就可以在 class 中发送任何内容。它编译得很好,但如果我尝试发送一个简单的字符串,打包在 class 中,我会得到一个 NotSerializableException。是否有任何属性或字段无法转换为流,或者我应该将 class 更改为通用的?我不是流和网络方面的专家,所以我非常感谢我能得到的每一点帮助和解释。
注意:我不是以英语为母语的人,如有任何 spelling/grammar 问题,请原谅。
java.io.NotSerializableException
,这意味着您的 object
或该对象的任何 non-transient
属性 未实现 Serializable
界面。在您的情况下, DataPackage
不是可序列化的。 Serializable
是一个标记 interface
,它基本上告诉 JVM
Serializable
类型的任何 instance
都可以序列化。在这里您可以浏览 Serializable and NotSerializableException.
您应该实现 Serializable 接口,以便 class 通过网络传输。
将 class 的第一行更改为:
import java.io.Serializable;
public class DataPackage implements Serializable{
您的 class 应该实现 Serializable 接口。
另请注意,您的 class 的每个 属性,在您的情况下 object 也应实现此接口,以便序列化正常工作。
所以我会考虑使这个 class 通用以强制对象实现 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;
}
}
通过这种方式,您可以确保您尝试发送的对象都是可序列化的。
如果你不想使用泛型,那么像这样制作可序列化类型的 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;
}
}