2010-12-13 16 views
8

¿Alguien sabe cómo se serializa un java.util.Date? Me refiero a explicarme exactamente qué es cada byte. Traté de escribir una fecha larga y luego una y puedo ver coincidencias, pero hay otros personajes que simplemente no entiendo.Serializando java.util.Date

Nuestra aplicación realiza solicitudes de servidor con datos, lo que significa que se serializa de cliente a servidor. El equipo que realiza pruebas de estrés utiliza una herramienta que captura estas solicitudes y las modifica, el problema es que quieren procesar las fechas y no sé cómo interpretar la secuencia de bytes. El tipo me refiero a parece estar dispuesto a aprender, pero hasta ahora no he encontrado nada que entiendo a él para que apunte ...

Código utilicé:

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:

la salida de la anterior es:

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

el tiempo es "w, áqÇ-" así que lo que es la materia entre el largo y el objeto de la fecha, es decir, "hjKYt XP"

NOTA algunos espacios en blanco son caracteres no imprimibles NULL, SOH, retroceso, etc. Entiendo que es el valor hexadecimal lo que importa.

EDIT:

sigue teniendo problemas. Por alguna razón, la solicitud HTTP serializada no serializa la fecha exactamente como la respuesta que acepté. Muy cerca pero aún diferente y no sé por qué. Lo que es aún más extraño es que cuando simplemente serializo una fecha parece funcionar bien. FYI en worj utilizamos Websphere 6.1 Estos son algunos ejemplos de lo que se envía en la petición:

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 

he podido identificar la mayoría de los campos, pero no el tiempo real! Por ejemplo la serialVersionUID es hj\\x81\\x01KYt\\x19

EDITAR (FINAL):

me encontré con la fecha pero no está cerca de donde era de esperar! Fue mucho después de la muestra que tenía porque estaban apareciendo otros campos de datos. Pensé que la fecha estaba hecha. ¡Fue solo una casualidad que noté el patrón hexadecimal de la fecha que estaba buscando! Ejemplo:

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 

¡El valor de la fecha está justo al final!

Respuesta

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

por lo tanto, es el valor a largo que representa el desplazamiento desde enero 1ro 1,970 00:00:00 GMT en milisegundos.

EDIT: sin embargo, esto es precedido y sucedido por algunas cabeceras:

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

¿Y los "otros personajes que simplemente no entiendo"? –

8

Los detalles del formato de serialización de objetos Java se especifican en Java Object Serialization Specification. Aparte de la magia y los números de versión, los detalles de la clase Date y el hecho de que el objeto es un Date se escribe en la secuencia.

El API doc for Date serialised form es:

El valor devuelto por getTime() es emitida (largo). Esto representa el offset desde el 1 de enero de 1970, 00:00:00 GMT en milisegundos.

Tenga en cuenta que realmente rompe la especificación al no llamar a defaultWriteObject o putFields.

Cuestiones relacionadas