2011-01-04 6 views
1

У меня есть сервер, на котором я отслеживаю некоторые данные. Когда я подключаюсь к серверу с помощью приложения-администратора, чтобы проверить текущее состояние данных. Я использую частоту обновления 5 секунд. В первый раз, когда сервер отправляет данные, он работает. Но во второй раз, когда данные изменились, администратор не получает обновленные данные. Я посылаю данные, завернутые в классе, через ObjectOutputStream и ObjectInputStream:Java: сериализация не работает во второй раз

Это класс-оболочки для данных:

public class Leerling implements Serializable { 

    public int llnID; 

    public String naam; 
    public String voornaam; 
    public String klas; 
    public int klasNummer; 
    public Date geboorteDatum; 

    public String getFullName() 
    { 
     return voornaam + " " + naam; 
    } 

    @Override 
    public String toString() { 
     return "Leerling{" + "llnID=" + llnID + ", naam=" + naam + ", voornaam=" + voornaam + ", klas=" + klas + ", klasNummer=" + klasNummer + ", geboorteDatum=" + geboorteDatum + '}'; 
    } 

} 


public class SLeerling extends Leerling implements Serializable{ 

    public boolean voted; 
    public int vote = -2; 
} 

То, что я попытался это перед чтением объекта из потока в звоните System.gc();, чтобы убедиться, что объект старый объект больше не в памяти. Но безуспешно.

Кто-нибудь знает, в чем проблема? И как сделать возможным получение реальных актуальных данных?

Заранее благодарен.


Второй пример проблемы:

я снова класс обертка для некоторых других данных (Это внутренний класс):

public static class MonitorResponse implements Serializable 
{ 
    public int numberOfLLN; 
    public int blocked; 
    public int blancos; 
    public List<Integer> votes; 
} 

При отправке данных первым время, это работает. Но во второй раз, когда я его отправлю (чтобы его обновить), все EXCEPT List<Integer> votes обновлено. Так что votes не обновляется. Тогда я решил его немного сложнее, заменив список с помощью массива:

public static class MonitorResponse implements Serializable 
{ 
    public int numberOfLLN; 
    public int blocked; 
    public int blancos; 
    public Integer[] votes; 
} 

И это отлично работает. Странно, если вы спросите меня. В другой части кода я почти ничего не менял ... (за исключением того, чтобы реализовать массив вместо списка)

+0

Из информации, предоставленной Вами до сих пор, это не звучит, как это не имеет ничего общего с сериализации. Это больше похоже на проблему с кешированием и обновлением на вашей странице администратора. Простое обновление за 5 секунд не помогает, если данные, которые вы получаете при обновлении, устарели. – rfeak

+0

Попробуйте поместить отметку времени в конце возвращаемых данных, чтобы убедиться, что браузер не кэширует ее. –

+0

@ Майкл: Я не пользуюсь браузером. Я использую собственное приложение для рабочего стола Java (а не апплет) –

ответ

5

Возможно, это ObjectOutputStream вызывает проблемы.

Если вы используете один объект ObjectOutputStream на сервере, вам необходимо убедиться, что вы вызываете его reset, иначе он будет писать общие ссылки на ранее написанные объекты. Это похоже на то, что вы видите.

Чтобы проиллюстрировать эту проблему:

class BrokenServer { 
    void sendBrokenVoteData(ObjectOutputStream out) { 
     out.writeObject(votes); 
     changeVoteData(votes); 
     out.writeObject(votes); // Writes a shared reference to "votes" WITHOUT updating any data. 
    } 
} 

class FixedServer { 
    void sendFixedVoteData(ObjectOutputStream out) { 
     out.writeObject(votes); 
     changeVoteData(votes); 
     out.reset(); // Clears all shared references. 
     out.writeObject(votes); // Writes a new copy of "votes" with the new data. 
    } 
} 
+0

, вы также можете использовать метод OOS.writeUnshared(). – jtahlborn

+0

Спасибо! Большое спасибо! –

+0

@jtahlborn 'writeUnshared' по большей части бесполезен. Unshared является неглубоким, поскольку другие объекты, на которые объект указывает все, будут совместно использоваться. –

Смежные вопросы