使用readObject()

时间:2017-01-12 15:08:31

标签: java sockets oop objectinputstream

我在客户端有一个bean类,它存储用户输入数据并通过套接字发送到服务器。服务器具有相同的bean类。

服务器接收对象,但是当我尝试将收到的内容分配给bean类的实例时,会导致以下错误:

java.lang.ClassCastException: ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client

有错误的类:

public class DriveableImpl implements Driveable{

    private Client client; 
    private ObjectOutputStream out; 
    private ObjectInputStream in; 

    public DriveableImpl() {
        client = new Client(); 
    }

    // Method that receives connection socket and open in/out streams for current session
    @Override
    public void connect(Socket socket){
        try {
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean login() throws Exception {

        // Program crash here
        client = (Client) in.readObject();
        System.out.println(client.toString());

        return false;
    }
}

我使用InvocationHandler调用上面类中实现的方法:

public class MethodInvoker implements InvocationHandler{

    private Object returnObject = null; // object that will hold any returns from invoked methods
    private final Driveable userInterface; 


    protected MethodInvoker(Driveable ui) {
        this.userInterface = ui;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
                  throws IllegalAccessException, IllegalArgumentException,
                  InvocationTargetException{

        System.out.println("BEFORE");
        returnObject = method.invoke(userInterface, args);
        System.out.println(method.getName());
        System.out.println("AFTER");

        return returnObject; // could problem be possibly here?
    }
}

我真的不确定这里发生了什么,因为它适用于简单的Client-Server应用程序设计。 在我看来,我发布了与错误相关的程序部分,但如果发出任何请求,我会修改帖子。

谢谢!

1 个答案:

答案 0 :(得分:2)

请注意序列化错误:

它清楚地表明你有2个不同的类(也许它们看起来完全相同)但它们在不同的包中:

ie.gmit.sw.**client**.methods
ie.gmit.sw.**server**.methods

这意味着,从Java的角度来看,它们完全不相关

ie.gmit.sw.client.methods.Client cannot be cast to ie.gmit.sw.server.methods.Client

这就是为什么你有一个类强制转换异常的原因

在Java中,相同类意味着它驻留在同一个包中并具有相同的名称。所以你应该在服务器和客户端都有相同的类。 有两种方法可以实现这一目标:

  • 只需将同一个类放两次 - 一次放在客户端,一次放在服务器中。在你的情况下,它意味着 - 重命名包是常见的。由于代码重复,这是一种糟糕的方法

  • 将通过序列化的对象放入第三个" common"模块(jar将由它生成),当你运行客户端和服务器使它们依赖于这个模块。实际上,你只有一份课程副本"客户"。