2010-12-13 16 views
8

Czy ktoś wie, w jaki sposób java.util.Date jest serializowany? Mam na myśli wyjaśnić mi dokładnie, co każdy bajt jest? Próbowałem napisać długą datę, a widzę mecze, ale są też inne postacie, których po prostu nie dostaję.Serializing java.util.Date

Nasza aplikacja sprawia, że ​​żądania serwera są wysyłane z danymi, co oznacza, że ​​jest ona przekształcana do postaci szeregowej z klienta na serwer. Zespół przeprowadzający testy warunków skrajnych używa narzędzia, które przechwytuje te żądania i modyfikuje je, problemem jest to, że chcą przetwarzać daty i nie wiem, jak interpretować strumień bajtów. Koleś mówię wydaje się chętny do nauki, ale do tej pory nie znalazłem nic, że rozumiem go do punktu ...

kod użyłem:

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(); 
    } 

EDIT:

wyjście z powyższego jest:

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

długa jest „w, áqÇ-”, więc to, co jest rzeczy między długa i obiektu Date, czyli „hjKYt XP”

UWAGA niektóre puste znaki są niedrukowalne. NULL, SOH, backspace itp. Rozumiem, że liczy się wartość heksadecymalna.

EDYTOWANIE:

Nadal występują problemy. Z jakiegoś powodu zsekwencjonowane żądanie HTTP nie przekształca daty w taki sam sposób, jak przyjęta przeze mnie odpowiedź. Bardzo blisko, ale wciąż inaczej i nie wiem dlaczego. Co jest jeszcze dziwniejsze, gdy po prostu serializuje datę, wydaje się działać dobrze. FYI w worj używamy Websphere 6.1 Oto kilka przykładów tego, co jest wysyłane na żądanie:

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 

byłem w stanie zidentyfikować większości dziedzin, ale nie rzeczywisty czas! Np z serialVersionUID jest hj\\x81\\x01KYt\\x19

EDIT (końcowy):

znalazłem datę, ale nie było gdzie w pobliżu, gdzie spodziewałem się! Było dobrze po tym, jak miałem próbkę, ponieważ pojawiły się inne pola danych. Myślałem, że data została zrobiona - to tylko fuks, że zauważyłem szesnastkowy wzór daty, której szukałem! Przykład:

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 

Wartość daty jest tuż na samym końcu!

Odpowiedz

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()); 
} 

dlatego, że to długo wartość reprezentująca offsetu od 1 stycznia 1970 00:00:00 GMT w milisekundach.

EDIT: jednak to jest poprzedzona i zastąpiony przez niektórych nagłówków:

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

I "inne postacie, których po prostu nie dostaję"? –

8

Szczegóły formacie Java serializacji obiektu są określone w Java Object Serialization Specification. Inne niż magiczne i numery wersji, szczegóły klasy Date i fakt, że obiekt jest Date jest zapisany w strumieniu.

API doc for Date serialised form jest:

Wartość zwracana przez GetTime() jest emitowane (długości). To oznacza przesunięcie od 1 stycznia 1970, 00:00:00 GMT w milisekundach.

Pamiętaj, że w rzeczywistości łamie specyfikację, nie dzwoniąc pod numer defaultWriteObject lub putFields.

Powiązane problemy