Jackson串行化java.time.Instant与WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS默认启用。
Jackson
java.time.Instant
WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
它产生JSON像这样
JSON
{ "timestamp":1421261297.356000000 }
我想知道是否有一种方法可以消除最后的零。我想要类似的东西:
{ "timestamp":1421261297.356 }
我试过了:
mapper.configure( SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false ); mapper.configure( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true );
但是此配置将其更改为毫秒表示1421261297356。我想要秒部分和小数毫秒部分。
1421261297356
当我们使用Java 8 Timepackage时,Jackson最好使用jackson-modules- java8项目,该项目可以使用许多序列化程序和反序列化程序。要启用它,我们需要注册JavaTimeModule模块。要序列化Instant InstantSerializer,请使用。当我们检查它的实现方式时,我们会发现在后台使用了DecimalUtils.toDecimal方法。看起来在纳秒值的末尾总是添加零。
Java 8
Time
JavaTimeModule
Instant
我们可以编写InstantSerializer以所需方式对其进行序列化的代码。由于该项目中的类尚未准备好轻松扩展,因此我们需要实现许多不需要的方法和构造函数。另外,我们需要在项目com.fasterxml.jackson.datatype.jsr310.ser包中创建并在其中创建实现。请参见以下示例:
InstantSerializer
com.fasterxml.jackson.datatype.jsr310.ser
package com.fasterxml.jackson.datatype.jsr310.ser; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.math.BigDecimal; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.function.ToIntFunction; import java.util.function.ToLongFunction; public class ShortInstantSerializer extends InstantSerializerBase<Instant> { private ToLongFunction<Instant> getEpochSeconds = Instant::getEpochSecond; private ToIntFunction<Instant> getNanoseconds = i -> i.getNano() / 1_000_000; public ShortInstantSerializer() { super(Instant.class, Instant::toEpochMilli, Instant::getEpochSecond, Instant::getNano, null); } protected ShortInstantSerializer(ShortInstantSerializer base, Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter) { super(base, useTimestamp, useNanoseconds, formatter); } @Override protected JSR310FormattedSerializerBase<?> withFormat(Boolean useTimestamp, DateTimeFormatter formatter, JsonFormat.Shape shape) { return new ShortInstantSerializer(this, useTimestamp, null, formatter); } @Override public void serialize(Instant value, JsonGenerator generator, SerializerProvider provider) throws IOException { if (useTimestamp(provider)) { if (useNanoseconds(provider)) { generator.writeNumber(new BigDecimal(toShortVersion(value))); return; } } super.serialize(value, generator, provider); } private String toShortVersion(final Instant value) { return getEpochSeconds.applyAsLong(value) + "." + padWithZeros(getNanoseconds.applyAsInt(value)); } private String padWithZeros(final int value) { return String.format("%1$3s", String.valueOf(value)).replace(' ', '0'); } }
并举例说明如何使用它:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.ser.ShortInstantSerializer; import java.time.Instant; public class JsonApp { public static void main(String[] args) throws Exception { JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(Instant.class, new ShortInstantSerializer()); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(javaTimeModule); mapper.disable(SerializationFeature.INDENT_OUTPUT); System.out.println(mapper.writeValueAsString(new Element())); } } class Element { private Instant timestamp = Instant.now(); public Instant getTimestamp() { return timestamp; } public void setTimestamp(Instant timestamp) { this.timestamp = timestamp; } }
上面的代码打印:
{"timestamp":1559074287.223}
如果要在所有情况下都消除全零,则编写您自己的getNanoseconds在ShortInstantSerializer类中声明的函数。
getNanoseconds
ShortInstantSerializer