2015-01-08 2 views
3

У меня было самое страшное время для работы с наносекундами при разборе с объекта на json и наоборот. Я создал самое простое использование Джексона, и я не могу получить наносекунды. Ниже приведена моя демонстрация. В часто задаваемых вопросах quickxml есть три важных утверждения, которые относятся к моему делу. Первые два дают мне трюк, чтобы сделать работу, а третий говорит не использовать sql.Date, но sql.timestamp является «сыном» sql.Date.можно использовать Джексон с наносекундным значением

Вопросы являются:

Во-первых, mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true) и @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS") не принимать вообще никакого эффекта. Я могу поставить false, true, даже не использовать mapper.configure, использовать или нет @JsonFormat и результат будет таким же,

Во-вторых, если я пытаюсь только десериализации, я имею в виду, введите значение 2015-01-07 11:37:52.390452 в user.json и работать только mapper.readValue Я получу значение 2015-01-07 11:44:22.452, поэтому я пропущу точное значение, потому что Жасксон округляется.

от http://wiki.fasterxml.com/JacksonFAQDateHandling

1 - Feature.WRITE_DATES_AS_TIMESTAMPS, ложные); которые запрещают использовать отметки времени (цифры) и вместо этого используют нотацию [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(); 
      } 
    } 
} 

// ПОМ (соответствующая часть только)

<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.Date или java.sql.Timestamp (при условии, что вы не отключили настройку Jackson DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS и SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, которые включены по умолчанию).

Перед Java 8 вы можете использовать java.math.BigDecimal для хранения количества дней с момента дробного времени и времени. Или просто сохраните значение в представлении String. Java 7 и предыдущие версии не сохраняют наносекунды в датах, только миллисекунды. Поэтому, если вы преобразуете значение в java.util.Date или один из его подклассов, например java.sql.Timestamp, вы получите точность только до миллисекунд. Поэтому java.text.DateFormat здесь не полезен, если вы используете его для преобразования в любой вид java Date в среде pre-Java 8.

Вот дальнейшее обсуждение наносекунд в ява отметки времени: java.sql.Timestamp way of storing NanoSeconds

+0

Будем говорить, что у меня есть устаревшие приложения с классами 100 Pojo в области слоя, и я не нужно использовать их для сериализации и десериализации в Json/Object (примите этот сценарий). Все они имеют как минимум один атрибут sql.timestamp. Что такое рекомендация эксперта команды Джексона? Должен ли я изменить код с Timestamp на String или BigDecimal? Это реальное решение, предложенное по спецификации Джексона, когда сталкивается с наносекундами? Timestamp.valueOf (новый SimpleDateFormat ("yyyy-MM-dd HH: mm: ss.SSSSSS") печатает наносекунды. Должен ли использоваться String в pojo для этого случая? –

+0

Addtionally, следует ли рассматривать mapper.configure (DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, true)/mapper.configure (SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, true) как невозможная возможность. Я прочитал несколько примеров, воспользовавшись этим, но я определенно не мог заставить простое приветственное слово вступить в силу этой функцией. –

+1

Извинения, похоже, что Java 8 имеет добавлена ​​поддержка наносекунд в классах Date.Я обновил свой ответ, чтобы отразить это. Надеюсь, ваше приложение работает на Java 8, поэтому вы можете воспользоваться этим усовершенствованием. – gknicker

Смежные вопросы