我想實現一個簡單的服務器,它能夠從客戶端接收一個對象。從客戶端發送的對象是在服務器端接收(投射)的對象的子類。從客戶端發送一個對象到服務器
編輯:如果我使用相同的子類「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