我目前正在为将来的项目在一个简单的服务器 - 客户端结构上工作。我决定最好使用自定义标头信息(例如本地/公共 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。是否有任何属性或字段无法转换为流,或者我应该将类更改为泛型?我不是流和网络方面的专家,所以我非常感谢我能得到的每一点帮助和解释。
注意:我不是母语为英语的人,请原谅任何拼写/语法问题。
您应该实现可序列化接口,以便通过网络传输类。
将类的第一行更改为:
import java.io.Serializable;
public class DataPackage implements Serializable{
当对象不可序列化时会抛出java.io.NotSerializableException
,这意味着该对象的object
或任何non-transient
属性不实现Serializable
接口。在您的情况下,DataPackage
不可序列化。Serializable
是一个标记interface
,它基本上告诉JVM
Serializable
类型的任何instance
都可以序列化。在这里,您可以浏览Serializable和NotSerializableException的文档。
你的类应该实现可序列化接口。
另请注意,类的每个属性(在您的 case中,对象也应实现此接口,以便序列化正常工作。
所以我会考虑使这个类泛型以强制对象实现可序列化接口。
编辑:例如,如果您尝试序列化包含字节缓冲区(不可序列化)的数据包,如下所示: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;
}
}
通过这种方式,您可以确定您尝试发送的对象都是可序列化的。
如果您不想使用泛型,请像这样使类型为可序列化的对象:
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;
}
}