当我通过writeObject方法发送对象时,为什么对象不会改变?

时间:2016-12-09 10:43:09

标签: java sockets objectinputstream objectoutputstream

我正在使用Java制作网络程序。作为标题,服务器尝试发送的对象在接收它的客户端中更改。在我从服务器收到新对象之前,我试图更改客户端中存在的对象。 这是我的代码。第一个是Server.sendIdea,第二个是Client.rcvIdea。

void sendIdea(Idea _idea) throws IOException {
    objectOS.flush();
    Idea idea = _idea;
//when I look into 'idea' it's fine
    objectOS.writeObject(idea);
}

...

Idea rcvIdea(int _ideaCode) throws ClassNotFoundException, IOException {
    objectOS.writeObject("sendIdea");
    objectOS.writeObject(_ideaCode);
    Idea returnValue = (Idea) objectIS.readObject();
//when I look into 'returnValue', it is not the one 'sendIdea' has sent.
    return returnValue;
}

如您所见,sendIdea(Idea _idea)正在使用Idea方法从班级writeObject发送对象。并且rcvIdea()正在使用readObject()方法接收对象。 (我确定你不必详细了解课程Idea)。通过这种方法,客户端在该程序开始时实际上收到了一些Idea,并且没有问题。但是当我尝试通过此方法接收相同但略微更改的对象Idea时,在Client类中对象不会更改,而不像Server类中的对象将要更改由sendIdea方法发送的方法已正确更改。我尝试了大约5个小时来解决这个问题。我逐行检查了所有代码,一无所获。我很确定writeObject或readObject方法有问题。我试过objectOS.flush()以清除流和许多其他试验。我希望我能找到问题。以下是我的程序中的一些代码

Client.class     包装想法海洋;

import java.awt.HeadlessException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import data.Idea;
import data.Opinion;
import data.Profile;

public class Client {
Socket socket;
OutputStream os;
ObjectOutputStream objectOS;
InputStream is;
ObjectInputStream objectIS;
MainWindow mainWindow;

int idCode;
String email, password;
Profile myProfile;
ArrayList<Idea> myIdeas;
ArrayList<Opinion> myOpinions;
ArrayList<Integer> newIdeasCodes, hotIdeasCodes;
ArrayList<Idea> newIdeas, hotIdeas;

String command;

static final String SERVER_IP = "127.0.0.1";// 
static final int SERVER_PORT_NUM = 5000;

public static void main(String[] args) {
    Client client = new Client();
    client.mainWindow = new MainWindow();

    client.mainWindow.setVisible(true);

    client.mainWindow.showLoginPg();
    try {
        while (!client.loginCheck()) {// login
            continue;
        }
    } catch (HeadlessException | NumberFormatException | ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }
    System.out.println("[login complete]");

    try {
        client.myProfile = client.rcvProfile(client.idCode);// get myProfile
        int i;
        for (i = 0; i < client.myProfile.myIdeaCode.size(); i++) {
            client.myIdeas.add(client.rcvIdea(client.myProfile.myIdeaCode.get(i)));
        }
        for (i = 0; i < client.myProfile.myOpinionCode.size(); i++) {
            client.myOpinions.add(client.rcvOpinion(client.myProfile.myOpinionCode.get(i)));
        }
        // ***************************
    } catch (ClassNotFoundException | IOException e1) {
        e1.printStackTrace();
    }

    try {
        client.rcvNewIdeas(12);
        client.mainWindow.newOcean.floatingIdeas = client.newIdeas;
        client.mainWindow.newOcean.arrangeFloatingPanels();

        client.rcvHotIdeas(12);
        client.mainWindow.hotOcean.floatingIdeas = client.hotIdeas;
        client.mainWindow.hotOcean.arrangeFloatingPanels();
    } catch (ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }

    client.mainWindow.setMyPg(client.myProfile, client.myIdeas, client.myOpinions);
    client.mainWindow.showMainPg();

    client.start();
}

public Client() {
    try {
        socket = new Socket(SERVER_IP, SERVER_PORT_NUM);

        System.out.println("Connected to Server!");

        os = socket.getOutputStream();
        objectOS = new ObjectOutputStream(os);
        is = socket.getInputStream();
        objectIS = new ObjectInputStream(is);

        myIdeas = new ArrayList<>();
        myOpinions = new ArrayList<>();
        newIdeasCodes = new ArrayList<>();
        hotIdeasCodes = new ArrayList<>();
        newIdeas = new ArrayList<>();
        hotIdeas = new ArrayList<>();

    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

void start() {
    while (true) {
        try {
            if (mainWindow.newBtnClicked) {
                rcvNewIdeas(12);
                mainWindow.newOcean.floatingIdeas = newIdeas;
                mainWindow.newOcean.arrangeFloatingPanels();
                mainWindow.newBtnClicked = false;
            } else if (mainWindow.hotBtnClicked) {
                rcvHotIdeas(12);
                mainWindow.hotOcean.floatingIdeas = hotIdeas;
                mainWindow.hotOcean.arrangeFloatingPanels();
                mainWindow.hotBtnClicked = false;
            } else if (mainWindow.newOcean.detailBtnClicked) {

                updateIdeaDetailFrame(mainWindow.newOcean.clickedIdea);
                mainWindow.newOcean.detailBtnClicked = false;

            } else if (mainWindow.hotOcean.detailBtnClicked) {

                updateIdeaDetailFrame(mainWindow.hotOcean.clickedIdea);
                mainWindow.hotOcean.detailBtnClicked = false;

            } else if (mainWindow.ideaDetailFrame.saveOpinionBtnClicked) {

                sendOpinion(mainWindow.ideaDetailFrame.newOpinion);
                updateIdeaDetailMainPanel(rcvIdea(mainWindow.ideaDetailFrame.idea.ideaCode));
                mainWindow.ideaDetailFrame.saveOpinionBtnClicked = false;

            } else if (mainWindow.writeIdeaPg.postIdeaBtnClicked) {

                sendIdea(mainWindow.writeIdeaPg.thisIdea);
                mainWindow.writeIdeaPg.postIdeaBtnClicked = false;

            } else if (mainWindow.newOcean.plusBtnClicked) {

                objectOS.writeObject("plusBtnClicked");
                objectOS.writeObject(mainWindow.newOcean.plusMinusClickedIdeaCode);
                mainWindow.newOcean.plusBtnClicked = false;

            } else if (mainWindow.newOcean.minusBtnClicked) {

                objectOS.writeObject("minusBtnClicked");
                objectOS.writeObject(mainWindow.newOcean.plusMinusClickedIdeaCode);
                mainWindow.newOcean.minusBtnClicked = false;

            } else if (mainWindow.hotOcean.plusBtnClicked) {

                objectOS.writeObject("plusBtnClicked");
                objectOS.writeObject(mainWindow.hotOcean.plusMinusClickedIdeaCode);
                mainWindow.hotOcean.plusBtnClicked = false;

            } else if (mainWindow.hotOcean.minusBtnClicked) {

                objectOS.writeObject("minusBtnClicked");
                objectOS.writeObject(mainWindow.hotOcean.plusMinusClickedIdeaCode);
                mainWindow.hotOcean.minusBtnClicked = false;

            } else if (mainWindow.myBtnClicked) {

                mainWindow.setMyPg(myProfile, myIdeas, myOpinions);
                mainWindow.myBtnClicked = false;
            }
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}

int i = 0;

Idea rcvIdea(int _ideaCode) throws ClassNotFoundException, IOException {
    objectOS.writeObject("sendIdea");
    objectOS.writeObject(_ideaCode);
    Idea returnValue = (Idea) objectIS.readObject();
    return returnValue;
}

Opinion rcvOpinion(int _opinionCode) throws ClassNotFoundException, IOException {
    objectOS.writeObject("sendOpinion");
    objectOS.writeObject(_opinionCode);
    return (Opinion) objectIS.readObject();
}

Profile rcvProfile(int _idCode) throws IOException, ClassNotFoundException {
    objectOS.writeObject("sendProfile");
    objectOS.writeObject(_idCode);
    return (Profile) objectIS.readObject();
}

void rcvNewIdeasCodes() throws ClassNotFoundException, IOException {
    objectOS.writeObject("sendNewIdeasCodes");
    newIdeasCodes = (ArrayList<Integer>) objectIS.readObject();
}

void rcvHotIdeasCodes() throws IOException, ClassNotFoundException {
    objectOS.writeObject("sendHotIdeasCodes");
    hotIdeasCodes = (ArrayList<Integer>) objectIS.readObject();
}

void rcvNewIdeas(int num) throws ClassNotFoundException, IOException {
    int i;
    rcvNewIdeasCodes();
    newIdeas = new ArrayList<>();
    if (num <= newIdeasCodes.size()) {
        for (i = 0; i < num; i++) {
            newIdeas.add(rcvIdea(newIdeasCodes.get(i)));
        }
    } else {
        for (i = 0; i < newIdeasCodes.size(); i++) {
            newIdeas.add(rcvIdea(newIdeasCodes.get(i)));
        }
    }
}

void rcvHotIdeas(int num) throws ClassNotFoundException, IOException {
    int i;
    rcvHotIdeasCodes();
    hotIdeas = new ArrayList<>();
    if (num <= hotIdeasCodes.size()) {
        for (i = 0; i < num; i++) {
            hotIdeas.add(rcvIdea(hotIdeasCodes.get(i)));
        }
    } else {
        for (i = 0; i < hotIdeasCodes.size(); i++) {
            hotIdeas.add(rcvIdea(hotIdeasCodes.get(i)));
        }
    }
}

void sendIdea(Idea _idea) throws IOException {
    objectOS.writeObject("rcvIdea");
    objectOS.writeObject(_idea);
}

void sendOpinion(Opinion _opinion) throws IOException {
    objectOS.writeObject("rcvOpinion");
    objectOS.writeObject(_opinion);
}

void sendProfile(Profile _profile) throws IOException {
    objectOS.writeObject(_profile);
}

boolean loginCheck() throws HeadlessException, NumberFormatException, IOException, ClassNotFoundException {
    objectOS.writeObject("loginCheck");// send command

    while (!mainWindow.loginBtnClicked) {
        continue;
    }
    mainWindow.loginBtnClicked = false;

    email = mainWindow.emailField.getText().trim();
    password = mainWindow.passwordField.getText().trim();
    objectOS.writeObject(email);
    objectOS.writeObject(password);

    boolean valid;
    valid = (boolean) objectIS.readObject();
    if (valid == false) {
        JOptionPane.showMessageDialog(mainWindow, "ID or Password is not correct");
        mainWindow.emailField.setText("");
        mainWindow.passwordField.setText("");
        return false;
    } else if (valid == true) {
        idCode = (int) objectIS.readObject();
        return true;
    } else {
        return false;
    }
}

void updateIdeaDetailMainPanel(Idea clickedIdea) throws ClassNotFoundException, IOException {
    ArrayList<Opinion> opinions = new ArrayList<>();
    for (int j = 0; j < clickedIdea.opinionCode.size(); j++) {
        opinions.add(rcvOpinion(clickedIdea.opinionCode.get(j)));
    }
    mainWindow.ideaDetailFrame.updateMainPanel(opinions);
}

void updateIdeaDetailFrame(Idea clickedIdea) throws ClassNotFoundException, IOException {
    ArrayList<Opinion> opinions = new ArrayList<>();
    for (int j = 0; j < clickedIdea.opinionCode.size(); j++) {
        opinions.add(rcvOpinion(clickedIdea.opinionCode.get(j)));
    }
    mainWindow.ideaDetailFrame = new IdeaDetailFrame(clickedIdea, opinions);
    mainWindow.ideaDetailFrame.setVisible(true);
}
}

Idea.class     包数据;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;

public class Idea implements Serializable {

private static final long serialVersionUID = 123123L;
public int idCode;
public int ideaCode;

public int plus = 0, minus = 0;

public String ideaName;
public String oneLineExp;
public String explanation;
public ArrayList<Integer> opinionCode;
public Date date;
public MyCanvas image;

int hotDegree;

public Idea(int _idCode,int _ideaCode, String _ideaName, String _oneLineExp, String _explanation, MyCanvas _image) {
    this(_idCode,_ideaName,_oneLineExp,_explanation,_image);
    ideaCode = _ideaCode;

}

public Idea(int _idCode, String _ideaName, String _oneLineExp, String _explanation, MyCanvas _image) {
    this(_idCode,_ideaName,_oneLineExp,_explanation);
    image = _image;
}

public Idea(int _idCode, String _ideaName, String _oneLineExp, String _explanation){
    idCode = _idCode;
    oneLineExp = new String(_oneLineExp);
    ideaName = new String(_ideaName);
    explanation = new String(_explanation);
    date = new Date();
    opinionCode = new ArrayList<>();
}

public void saveIdea() {
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;

    try {
        fos = new FileOutputStream("Idea.dat");
        oos = new ObjectOutputStream(fos);

        oos.writeObject(this);
    } catch (IOException e1) {
        System.out.println("e1");
    }
}

void addOpinionCode(int _opinion) {
    opinionCode.add(opinionCode.size(), _opinion);
}

public void incPlus() {
    plus++;
}

public void incMinus() {
    minus++;
}

public int setHotDegree() {
    hotDegree = plus - minus + opinionCode.size() * 2;
    return hotDegree;
}

}

Opinion.class

package data;

import java.io.Serializable;
import java.util.Date;

public class Opinion implements Serializable{
int idCode;
public int opinionCode;//the intrinsic code of this opinion

public int commentedIdeaCode;
public String opinion;
public Date date;
int plus, minus;

public Opinion(int _idCode,int _commentedIdeaCode, String _opinion){
    idCode = _idCode;
    commentedIdeaCode = _commentedIdeaCode;
    opinion = new String(_opinion);
    date = new Date();
    plus = 0;
    minus = 0;
}// Opinion(int _idCode,int _commentedIdeaCode, String _opinion)

public Opinion(int _idCode,int _opinionCode,int _commentedIdeaCode, String _opinion){
    this(_idCode, _commentedIdeaCode, _opinion);
    opinionCode = _opinionCode;
}//Opinion(int _idCode,int _opinionCode,int _commentedIdeaCode, String _opinion)

void incPlus(){
    plus++;
}

void incMinus(){
    minus++;
}
}

1 个答案:

答案 0 :(得分:1)

ObjectOutputStream创建已经序列化的所有对象的图形,并使用对先前序列化对象的引用。因此,当您多次序列化Idea实例时,每次在第一个实例之后,将写入对第一个序列化的引用而不是完整对象。

每次序列化后都可以使用ObjectOutputStream.reset()。这将丢弃对象图并强制ObjectOutputStream创建新的对象序列化,即使对于之前看到的对象也是如此。

因此,您的sendIdea方法应如下所示:

void sendIdea(Idea _idea) throws IOException {
    objectOS.flush();
    objectOS.reset();

    Idea idea = _idea;
    objectOS.writeObject(idea);
}

非常重要的是,请注意在reset()之后,所有对象引用都会重新序列化。因此,如果您有一个复杂的对象图,则在反序列化后最终可能会出现对象重复。

如果您想要多次共享要序列化的对象的传递引用,请转而使用ObjectOutputStream.writeUnshared()