2015-01-08 20 views
3

我有最糟糕的可想象的時間來解析從對象到json和反之間的納秒。我創建了最簡單的傑克遜使用方法,我無法獲得納秒。以下是我的演示。 fastxml FAQ中有三個與我的案例有關的重要聲明。前兩個給我製作工作的竅門,第三個告訴我不要使用sql.Date,但sql.timestampsql.Date的「兒子」。是否有可能使用傑克遜納秒值

的問題是:

首先, mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true)@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")採取沒有任何影響。我可以把falsetrue,甚至沒有使用mapper.configure,使用或不@JsonFormat,結果將是相同的,

其次,如果我只嘗試反序列化,我的意思是,在user.json輸入值2015-01-07 11:37:52.390452只有運行mapper.readValue我會得到值2015-01-07 11:44:22.452,所以我錯過了確切的價值,因爲雅克斯森收起來了。

http://wiki.fasterxml.com/JacksonFAQDateHandling

1 - Feature.WRITE_DATES_AS_TIMESTAMPS,FALSE);禁止使用 時間戳(數字),而是使用[ISO-8601]兼容 表示法,該表示法將輸出爲如下形式: 「1970-01-01T00:00:00.000 + 0000」。

2 - 您可以通過傳遞java.text.DateFormat中

3配置格式 - 請不要使用java.sql.Date,永遠!

//的POJO

package com.jim.core; 


import java.sql.Timestamp; 
import com.fasterxml.jackson.annotation.JsonFormat; 


public class User { 

     @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS") 
     private Timestamp tsFirstTry; 

     private Timestamp tsSecondTry; 

     @Override 
     public String toString() { 
       return "User [tsFirstTry=" + tsFirstTry + ", tsSecondTry=" + tsSecondTry + "]"; 
     } 

     //getters and setters 
} 

//主類

package com.jim.core; 


import java.io.File; 
import java.io.IOException; 
import java.sql.Timestamp; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.TimeZone; 
import com.fasterxml.jackson.databind.DeserializationFeature; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializationFeature; 

public class Main { 
    public static void main(String[] args) { 

      User user = new User(); 
      user.setTsFirstTry(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()))); 

      user.setTsSecondTry(Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()))); 


      System.out.println("firstTryValue = "+ Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()))); 

      System.out.println("secondTryValue = "+ Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS").format(new Date()))); 

      ObjectMapper mapper = new ObjectMapper(); 

      try { 
       //mapper.setTimeZone(TimeZone.getTimeZone("UTC")); 
       //mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true); 

       //mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,true); 

       mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS")); 

       //Serialization - saving the created objects in the sequence of bytes. 
       mapper.writeValue(new File("c:\\temp\\user.json"), user); 
       System.out.println("Serialized Outcome = " + mapper.writeValueAsString(user)); 

       //Deserialization - Retrieving those saved bytes into the form of original object. 
       user = mapper.readValue(new File("c:\\temp\\user.json"), User.class); 
       System.out.println("Deserialized Outcome = " + user); 


      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 
} 

// POM(相關唯一部分)

<properties> 
    <java-version>1.6</java-version> 
    <jackson.databind-version>2.2.3</jackson.databind-version> 
</properties> 
<dependencies> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-databind</artifactId> 
     <version>${jackson.databind-version}</version> 
    </dependency> 

//控制檯

firstTryValue = 2015-01-08 11:31:53.000773 
secondTryValue = 2015-01-08 11:31:53.000773 

Serialized Outcome = {"tsFirstTry":"2015-01-08 17:31:53.000000","tsSecondTry":"2015-01-08 11:31:53.000000"} 

Deserialized Outcome = User [tsFirstTry=2015-01-08 11:31:53.0, tsSecondTry=2015-01-08 11:31:53.0] 

回答

6

是的,有可能使用傑克遜納秒的價值;要在Java 8中保留納秒,可以使用java.util.Datejava.sql.Timestamp(假設您尚未禁用Jackson配置DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDSSerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,這些默認情況下處於啓用狀態)。

在Java 8之前,您可以使用java.math.BigDecimal來存儲自時代以來的天數加上一天中的小數時間。或者只保留其字符串表示形式的值。 Java 7和以前的版本不會在日期中保持毫微秒,只有毫秒。因此,如果將該值轉換爲java.util.Date或其中一個子類java.sql.Timestamp,則只能精確到毫秒。因此,如果您正在使用它來轉換爲Java-8以前環境中的任何種類的java Date,那麼java.text.DateFormat在這裏沒有用處。

這裏是納秒在java中的時間戳進一步討論:java.sql.Timestamp way of storing NanoSeconds

+0

讓我們說,我在域層100 POJO類的遺留應用程序,我確實需要使用這些序列化和反序列化到JSON /對象敬請(請接受這種情況)。它們都至少有一個sql.timestamp屬性。什麼是傑克遜專家團隊推薦?我應該將Timestamp中的代碼更改爲String還是BigDecimal?這是從傑克遜規格提出的面對納秒時間的真正解決方案嗎? Timestamp.valueOf(新的SimpleDateFormat(「yyyy-MM-dd HH:mm:ss.SSSSSS」))會打印納秒,對於這種情況,必須在pojo中真的使用String嗎? –

+0

另外,我應該考慮mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true )/ mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS,true)作爲不可行的可能性。我讀了一些利用這個優勢的例子,但是我絕對無法讓這個簡單的hello單詞生效。 –

+1

抱歉,它看起來像Java 8一樣我已經更新了我的答案以反映這一點希望你的應用程序運行在Java 8上,這樣你就可以利用這個增強功能 – gknicker