2010-12-13 22 views
8

有誰知道java.util.Date是如何被序列化的?我的意思是說明每個字節到底是什麼?我試着寫出一個很長的日期,我可以看到比賽,但還有其他人物,我只是沒有得到。序列化java.util.Date

我們的應用程序使數據的服務器請求,這意味着它從客戶端到服務器序列化。進行壓力測試的團隊使用捕獲這些請求並修改它們的工具,問題是他們想要處理日期,而我不知道如何解釋字節流。我所說的花花公子似乎願意學習,但到目前爲止,我還沒有發現任何東西,我理解爲指向他...我用

代碼:

FileOutputStream fos = null; 
    ObjectOutputStream oos = null; 
    try 
    { 
    fos = new FileOutputStream("t.tmp"); 
    oos = new ObjectOutputStream(fos); 

    Date today = new Date(); 

    oos.writeLong(today.getTime()); 
    oos.writeObject("Today"); 
    oos.writeObject(today); 

    oos.close(); 
    } 
    catch(FileNotFoundException e) 
    { 
    e.printStackTrace(); 
    } 
    catch(IOException e) 
    { 
    e.printStackTrace(); 
    } 

編輯:

從上面的輸出是:

"¬í w ,áqÇ-t Todaysr java.util.DatehjKYt xpw ,áqÇ-x" 

長是「W,áqÇ-」究竟什麼是長期和Date對象,即「hjKYt XP」

的東西210

注意一些空格是不可打印的字符NULL,SOH,退格等等。我知道這是十六進制值。

編輯:

仍然有問題。出於某種原因,序列化的HTTP請求不會像我接受的答案那樣序列化日期。非常接近,但仍然不同,我不知道爲什麼。更奇怪的是,當我簡單地序列化日期時,它似乎工作正常。 FYI在worj我們使用WebSphere 6.1以下是在請求正在發送的一些例子:

lr_start_transaction("20000101"); 
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10\\x0BXxt\\x00\\x08 

lr_start_transaction("20000102"); 
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10>\\x9Dxt\\x00\\x08 

lr_start_transaction("20000103"); 
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10z\\xDBxt\\x00\\x08 

我已經能夠識別大多數領域,但不是實際的時間! E.g的serialVersionUID的是hj\\x81\\x01KYt\\x19

EDIT(最終):

我找到了日期,但它沒有在附近,我希望它!之後我的樣本已經完好無損,因爲其他數據字段出現了,我認爲日期已經完成 - 我注意到我正在尋找的日期的十六進制模式只是僥倖!例如:

lr_start_transaction("20000101"); 
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10\\x0BXxt\\x00\\x08OTTST153t\\x00\\x06/Web2/t\\x00\\x044971t\\x00\\x0B12ce12f737d\\x00\\x00\\x01,\\xE10\\x0BXsq\\x00~\\x00\\x0Fw\\x08\\x00\\x00\\x00\\xDCk\\xE2T\\x80xt 

日期值是正確的最後!

回答

5
/** 
* Save the state of this object to a stream (i.e., serialize it). 
* 
* @serialData The value returned by <code>getTime()</code> 
*   is emitted (long). This represents the offset from 
*    January 1, 1970, 00:00:00 GMT in milliseconds. 
*/ 
private void writeObject(ObjectOutputStream s) 
    throws IOException 
{ 
    s.writeLong(getTimeImpl()); 
} 

因此,它是表示從1970年1月1日00:00:00 GMT以毫秒爲單位的偏移量的長整型值。

編輯:但是這是由一些頭preceeded和成功:

0x73 - being the code for an ordinary object (TC_OBJECT)  
0x72 - being the code for a class description (TC_CLASSDESC)  
"java.util.Date" - the name of the class  
7523967970034938905L - the serialVersionUID  
0|0x02|0x01 - flags including SC_SERIALIZABLE & SC_WRITE_METHOD  
0 - number of fields  
0x78 - TC_ENDBLOCKDATA  
null - there is no superclass descriptor  
the time (long milliseconds since epoch)  
0x78 - TC_ENDBLOCKDATA 
+0

而「我只是沒有得到的其他字符」? – 2010-12-13 20:44:23

8

Java對象序列化格式的細節在Java Object Serialization Specification規定。除了魔術和版本號之外,Date類的詳細信息以及對象爲Date的事實被寫入到流中。

API doc for Date serialised form的是:

通過的getTime()返回的值是 發射(長)。這代表從1970年1月1日00:00:00 GMT以毫秒爲單位的偏移量 。

請注意,它實際上不打電話defaultWriteObjectputFields打破規範。