我想实现一个简单的服务器,它能够从客户端接收一个对象。从客户端发送的对象是在服务器端接收(投射)的对象的子类。从客户端发送一个对象到服务器
编辑:如果我使用相同的子类“TestMessage”正确的字符串打印在服务器端。如果我使用超类“消息”(我想这样做,因为我需要多个消息子类)字符串只是空。那么是否存在ObjectInputStream的特定属性,如果我将其投影到超类,它会弄乱我的字段或整个对象?
Payload on client side: Hello Server!
Payload on server side: null
我已经创建了一个抽象类消息,从该几个子类可以导出:
public abstract class Message implements Serializable {
private static Random random = new Random();
/**
* A 16-byte string (GUID) uniquely identifying the message on the network.
*/
private byte[] guid;
/**
* Indicates the type of message.
*/
private byte messageType;
/**
* The actual content of the message.
*/
private static String payload;
/**
* TODO change to protected?
* @return payload
*/
public static String getPayload() {
return payload;
}
/**
* TODO change to protected?
* @param payload
*/
public static void setPayload(String payload) {
payload = payload;
}
/**
* @return guid
*/
public byte[] getGuid() {
return guid;
}
/**
* @return messageType
*/
public byte getMessageType() {
return messageType;
}
/**
* Constructor for a newly created message
* @param messageType
*/
public Message(byte messageType) {
guid = new byte[16];
random.nextBytes(guid);
//TODO encrypt guid?
this.messageType = messageType;
}
/**
* Constructor for a received message
* @param guid
* @param messageType
*/
public Message(byte[] guid, byte messageType) {
this(messageType);
this.guid = guid;
}
}
现在,我有衍生的测试消息类型的TestMessage,其从客户端发送到服务器。
public class TestMessage extends Message {
private static byte TYPE_ID = (byte) 0x00;
/**
* @param payload
*/
public TestMessage(String payload) {
super(TYPE_ID);
/**
* TODO: Better practice to create a protected setter?
*/
Message.setPayload(payload);
}
}
现在服务器没什么特别的了。它等待客户端连接并从流中读取Message对象。这里我得到一个ClassNotFoundException。我想服务器类不知道消息类?为什么这样?客户端发送服务器读取的类的子类是否存在问题?或者我的Message类的转换有问题吗?
public class TestServer {
public static void main(String[] args) throws IOException {
int port = 9999;
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
Message incomingMessage = null;
incomingMessage = (Message)objectInputStream.readObject();
System.out.println("Payload: " + Message.getPayload());
}
}
最后,客户端:
public class TestClient {
public static void main(String[] args) throws IOException {
String serverAdress = "localhost";
int port = 9999;
Socket socket = new Socket(serverAdress, port);
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
TestMessage testMessage = new TestMessage("Hello Server!");
objectOutputStream.writeObject(testMessage);
}
}
谢谢你们提前!我希望有一个人可以帮助我。
您应提供完整的堆栈跟踪而不是完整的代码。至少在这里不需要冗长的接口代码。 –
服务器类路径中是否有'Message'结尾的'TestMessage'类可用? – toKrause
每个班级都在同一个包中,所以我认为这就够了。你是否在意解释如何将它们添加到类路径中?谢谢! – Ipsider