【问题标题】:ObjectInputStream returns an empty objectObjectInputStream 返回一个空对象
【发布时间】:2018-08-25 23:11:12
【问题描述】:

所以我试图将一个对象从客户端发送到服务器,然后我对这个对象做一些事情。我验证了在发送对象时包含数据。当我在调试器中读取我的对象时,它的所有属性都是空的。

下面是我发送对象的地方:

private class registerUser extends Task<Void>
{
        Users user;
        private static final String code = ".register";
        private static final String host = "localhost";
        private static final int portNumber = 4444;
        private clientThread clientThread;


    public registerUser(Users user)
    {
        this.user = user;
    }

    @Override
    protected Void call() throws Exception
    {
        try
        {
            Socket socket = new Socket(host, portNumber);
            Thread.sleep(1000);

            //Setup I/O
            ObjectOutputStream outToServerObject = new ObjectOutputStream(socket.getOutputStream());
            //PrintWriter serverOutString = new PrintWriter(socket.getOutputStream(), false);
            InputStream serverInString = socket.getInputStream();

            //serverOutString.println(code);
           // serverOutString.flush();

            outToServerObject.writeObject(user);
            outToServerObject.flush();
        }
        catch (IOException e)
        {
            System.err.println("Fatal Connection error!");
            e.printStackTrace();
        }
        return null;
    }

当我按下 GUI 中的按钮时,将使用上述任务,如下所示:

public void btn_registerUser(ActionEvent actionEvent) throws IOException
{

        user.setUserName(txt_Username.getText());
        user.setFirstName(txt_FirstName.getText());
        user.setLastName(txt_LastName.getText());
        user.setCity(txt_City.getText());
        user.setBirthday(date_Birthday.getValue());


        Task<Void> task = new registerUser(user);
        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();

}

接收对象的服务器中的代码:

//Setup I/O
this.clientOut = new PrintWriter(socket.getOutputStream(), false);
ObjectInputStream inFromClientObject = new ObjectInputStream(socket.getInputStream());


// Scanner in = new Scanner(socket.getInputStream());
Users user = (Users) inFromClientObject.readObject();
doSomething(user);

还有作为辩论对象的 User.java 类

public class Users implements Serializable
{

    /*
    Variables
    TODO Create a friend list
    */
    private transient IntegerProperty userID;
    private transient StringProperty userName;
    private transient StringProperty firstName;
    private transient StringProperty lastName;
    private transient StringProperty city;
    private transient ObjectProperty<LocalDate> birthday;
    private transient ListProperty<String> musicGenre;
    private transient List<String> musicGenres = new ArrayList<>();
    /**
     * Default constructor.
     */
    public Users()
    {
        this(null,null,null,null,null);
    }

    /**
     * Constructor with some initial data.
     * Takes in a {@code String} and sets a reference
     *
     * @param userName
     *
     */
    public Users(String userName,  String firstName, String lastName, String city, LocalDate birthday)
    {
        this.userName = new SimpleStringProperty(userName);
        this.userID = new SimpleIntegerProperty();
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
        this.city = new SimpleStringProperty(city);
        this.birthday = new SimpleObjectProperty<LocalDate>(birthday);
        ObservableList<String> observableList = FXCollections.observableArrayList(this.musicGenres);
        this.musicGenre = new SimpleListProperty<String>(observableList);

    }
}

我已经省略了 getter 和 setter,因为这个问题已经很长了

所以在调试器中运行服务器时,当我doSomething(user)时,用户的所有属性都为空

*编辑 这些建议正在奏效,但我遇到了问题

private List<String> musicGenreList = new ArrayList<>();
ObservableList<String> observableList = FXCollections.observableArrayList(musicGenreList);
private ListProperty<String> musicGenre = new SimpleListProperty<String>(observableList);

这是我可以将项目添加到 ListPropertyobservableList 无法序列化的唯一方法

【问题讨论】:

  • transient 表示“不要序列化这个值”。所以这正是你所期望的。 JavaFX 属性和集合不可序列化,您真的只想序列化它们的值。为此,您需要实现自定义序列化。见stackoverflow.com/questions/33452847/…stackoverflow.com/questions/23187989/…
  • 您还可以使用具有通常类型属性的所谓 DTO 对象,例如可序列化的StringInteger 等。然后将User 对象转换为UserDTO,序列化该DTO,发送,反序列化,从UserDTO 构造Users 对象并在另一台机器上使用它。
  • 或者说,流式 JSON。只要getset 方法以相同的方式命名,您就可以使用JavaFX 属性序列化对象并将其反序列化为表示与常规JavaBean 属性相同值的对象,反之亦然。
  • @James_D 除了我的 listProperty 之外,这一切都很好,我通过创建一个 arrayList 然后附加一个 FXCollection 可观察的 arraylist 来实现它。然后我创建了一个新的 ListProperty 作为new SimpleListProperty&lt;String&gt;(observableList);。当然这可以序列化,但这是我将项目添加到列表的唯一方法。有什么想法吗?

标签: java javafx


【解决方案1】:

就像 James_D 所说的,基本上我必须创建自定义 WriteExternalReadExternal

Users.java中需要进行修改

public class Users implements Externalizable
{
    public Users(String userName,  String firstName, String lastName, String city, LocalDate birthday)
    {
        setUserName(userName);
        setFirstName(firstName);
        setBirthday(birthday);
    }

    private IntegerProperty userID = new SimpleIntegerProperty(this, "id");
    private StringProperty userName = new SimpleStringProperty(this, "userName');
    private ObjectProperty<LocalDate> birthday = new SimpleObjectProperty<>(this, "birthday");

    //Create setters and getters...

    @Override
    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeInt(getUserID());
        out.writeObject(getUserName());
        out.writeObject(getBirthday());
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
    {
        setUserID((int) in.readInteger());
        setUserName((String) in.readObject());
        setBirthday((LocalDate) in.readObject());
    }
}

但是 我无法使用以下方法序列化 ListProperty

private ObservableList<String> observableList = FXCollections.observableArrayList();
private ListProperty<String> newList = new SimpleListProperty<>(this, "musicGenre", observableList);

根据我的需要,ListProperty 需要以这种方式实例化,因为我需要使用 user.newListProperty().get().add("String") 向它添加字符串项,而没有 ObservableList 我不能这样做

如果有人知道解决这个问题的方法,将不胜感激

【讨论】:

    猜你喜欢
    • 2013-11-09
    • 2012-06-08
    • 2021-03-31
    • 2014-07-15
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多