У меня было самое страшное время для работы с наносекундами при разборе с объекта на 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]
Будем говорить, что у меня есть устаревшие приложения с классами 100 Pojo в области слоя, и я не нужно использовать их для сериализации и десериализации в Json/Object (примите этот сценарий). Все они имеют как минимум один атрибут sql.timestamp. Что такое рекомендация эксперта команды Джексона? Должен ли я изменить код с Timestamp на String или BigDecimal? Это реальное решение, предложенное по спецификации Джексона, когда сталкивается с наносекундами? Timestamp.valueOf (новый SimpleDateFormat ("yyyy-MM-dd HH: mm: ss.SSSSSS") печатает наносекунды. Должен ли использоваться String в pojo для этого случая? –
Addtionally, следует ли рассматривать mapper.configure (DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, true)/mapper.configure (SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, true) как невозможная возможность. Я прочитал несколько примеров, воспользовавшись этим, но я определенно не мог заставить простое приветственное слово вступить в силу этой функцией. –
Извинения, похоже, что Java 8 имеет добавлена поддержка наносекунд в классах Date.Я обновил свой ответ, чтобы отразить это. Надеюсь, ваше приложение работает на Java 8, поэтому вы можете воспользоваться этим усовершенствованием. – gknicker