- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Jackson
使用默认启用的 WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
序列化 java.time.Instant
。
它像这样生成 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
。我想要秒部分和小数毫秒部分。
最佳答案
当我们使用 Java 8
Time
包和 Jackson
时,最好使用 jackson-modules-java8为许多准备使用的序列化器和反序列化器提供服务的项目。要启用它,我们需要注册 JavaTimeModule
模块。序列化 Instant
InstantSerializer用来。当我们检查它是如何实现的时,我们会发现幕后 DecimalUtils.toDecimal使用的方法。看起来总是在纳秒值的末尾添加零。
我们可以编写我们的 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
类中声明。
关于java - jackson 序列化即时到纳秒问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56345200/
根据这个问题:Fractional power of units of measures in F# F# 中的度量单位不支持分数幂。 在我的应用程序中,有时考虑带有度量前缀的数据是有益的,例如当处理
我是一名优秀的程序员,十分优秀!