我当前正在实现搜索功能,在该功能中,用户输入的字符串被发送到服务器,服务器通过数据库进行查找,并将其用户名与给定字符串匹配的所有用户发送回客户端。为了进行传输,我使用了一个自定义类Message
,该类包含一个包含要执行的动作的String(此处不相关)和一个对象,它是实际的消息。在这种情况下,该值为ArrayList<User>
。我使用writeObject()
中的ObjectOutputStream
方法和readObject()
中的ObjectInputStream
来传输数据。接收到数据后,我将该对象转换为Message对象,这是我得到异常的地方。注意:强制转换为Message在代码中的其他任何地方都可以正常工作,但是在此抛出异常。
例外:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.io.ObjectStreamClass cannot be cast to gruber.common.Message
at gruber.client.controller.ChatRoomController.lambda$searchForUser$2(ChatRoomController.java:105)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
客户端:
private void searchForUser(){
try {
oos.writeObject(new Message("SEARCH", searchfield.getText()));
oos.flush();
Message results = (Message)ois.readObject();
ArrayList<User> users = (ArrayList<User>)results.getMsg();
for(User u: users) {
System.out.println(u.getUsername());
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
服务器端:
private void search() throws SQLException, IOException {
Message client_msg = (Message) client.getOis().readObject();
String searchParam = client_msg.getMsg();
PreparedStatement searchUsers = con.prepareStatement("SELECT username, image from chatuser where username like ?");
searchUsers.setString(1, searchParam);
ResultSet results = searchUsers.executeQuery();
ArrayList<User> users = new ArrayList<>();
while (results.next()) {
users.add(new User(results.getString(1), results.getBytes(2)));
}
client.getOos().writeObject(new Message("SEARCH", users));
client.getOos().flush();
}
消息类(如果相关):
package gruber.common;
import java.io.Serializable;
public class Message implements Serializable {
private String action;
private Object msg;
public Message(String action, Object msg) {
this.action = action;
this.msg = msg;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Object getMsg() {
return msg;
}
public void setMsg(Object msg) {
this.msg = msg;
}
}
[如果类实现可序列化,则应使用可以自由定义的值定义属性serialVersionUID。
private static final long serialVersionUID = 1L;
如果不定义serialVersionUID,它将由java生成,并且在不同的JVM上可能会有所不同,从而导致对象无法在这些JVM之间互换。
由于您在谈论客户端和服务器,所以我认为JVM在客户端和服务器上可以不同。您的Message类实现了Serializable,但是没有定义serialVersionUID。尝试添加此属性。对您的用户对象同样有效。