I have had the worst imaginable time to work with nanoseconds while parsing from object to json and vice verse. I created the simplest possible use of Jackson and I can't get the nanoseconds. Below is my demonstration. There are three important statement in fasterxml FAQ that are related to my case. The first two give me the trick to make work and the third tells not to use sql.Date
but sql.timestamp
is "son" of sql.Date
.
The issues are:
Firstly,
mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,true)
and @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")
take no effect at all. I can place false
, true
, even not use mapper.configure
, use or not @JsonFormat
and the result will be the same,
Secondly, if I try only Deserialize, I mean, enter the value 2015-01-07 11:37:52.390452
in theuser.json
and only run mapper.readValue
I will get the value 2015-01-07 11:44:22.452
, so I miss the exact value because Jacskon round up.
from http://wiki.fasterxml.com/JacksonFAQDateHandling
1 - Feature.WRITE_DATES_AS_TIMESTAMPS, false); which disable use of timestamps (numbers), and instead use a [ISO-8601 ]-compliant notation, which gets output as something like: "1970-01-01T00:00:00.000+0000".
2 - You can configure formatting by passing a java.text.DateFormat
3 - Please do NOT use java.sql.Date, ever!
//the 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
}
//main class
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 (relevant part only)
<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>
//Console
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]
if enable Jackson will accept a single value as an array. If disabled, then the exception will be thrown. If enabled, it will unwrap a single value array and deserialize it into the corresponding datatype. If disabled, the exception will be thrown. If enabled, it will unwrap the root value.
Then to map ownerName, we unpack the nested owner object to a Map and extract its name property. We can instruct Jackson to unpack the nested property by using a combination of @JsonProperty and some custom logic that we add to our Product class:
Jackson allows you to read JSON into a tree model: Java objects that represent JSON objects, arrays and values. These objects are called things like JsonNode or JsonArray and are provided by Jackson. Jackson uses a class called ObjectMapper as its main entrypoint.
Maven Dependency Let's first add the following dependency to pom.xml: We can find the latest versions of jackson-databind on Maven Central. 3. JSON Source Consider the following JSON as the source material for our examples. While the structure is contrived, note that we include properties that are nested two levels deep: 4. Simplified Domain Model
Yes, it is possible to use Jackson with nanoseconds value; to preserve nanoseconds in Java 8 you can use java.util.Date
or java.sql.Timestamp
(assuming you haven't disabled Jackson configuration DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS
and SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
, which are enabled by default).
Before Java 8 you can use a java.math.BigDecimal
to store the number of days since epoch plus fractional time of day. Or just keep the value in its String representation. Java 7 and prior versions don't keep nanoseconds in dates, only milliseconds. So if you convert the value to a java.util.Date
or one of its subclasses like java.sql.Timestamp
, you will have precision only to milliseconds. Therefore java.text.DateFormat
is not useful here if you are using it to convert to any kind of java Date in a pre-Java 8 environment.
Here is a further discussion of nanoseconds in java Timestamps: java.sql.Timestamp way of storing NanoSeconds
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With