序列化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Ç-”所以long和Date对象之间的东西是什么,即“hjKYt xp”

注意一些空白是不可打印的字符NULL,SOH,退格等。我知道它是重要的hex值。

编辑:

还有问题。 由于某种原因,序列化的HTTP请求没有像我接受的答案那样序列化日期。 非常接近,但仍然不同,我不知道为什么。 甚至更奇怪的是,当我简单地序列化一个日期时,似乎工作得很好。 在我们使用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 

我已经能够识别大多数字段但不是实际时间! 例如,serialVersionUID是hj\\x81\\x01KYt\\x19

编辑(最终):

我找到了日期,但它没有在我预期的地方附近! 我的样本很好,因为其他数据字段出现我认为日期已经完成 – 只是侥幸,我注意到我正在寻找的日期的hex模式! 例:

  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 

日期值就在最后!

 /** * Save the state of this object to a stream (ie, serialize it). * * @serialData The value returned by getTime() * 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的偏移量的长值,以毫秒为单位。

编辑:然而这是一些标题之前和成功:

 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 

Java对象序列化格式的详细信息在Java对象序列化规范中指定。 除了魔术和版本号之外, Date类的详细信息和对象是Date的事实被写入流。

Date序列化表单的API文档是:

getTime()返回的值被发出(long)。 这表示从1970年1月1日00:00:00 GMT以毫秒为单位的偏移量。

请注意,它实际上是通过不调用defaultWriteObjectputFields破坏规范。