Jackson,java.time,ISO 8601,序列化无毫秒

Ben*_*n M 12 java jackson jackson-modules java-time jackson2

我正在使用Jackson 2.8并且需要与ISO 8601时间戳内不允许毫秒的API进行通信.

预期的格式是这样的: "2016-12-24T00:00:00Z"

我正在使用Jackson的JavaTimeModule WRITE_DATES_AS_TIMESTAMPS设置为false.

但这将打印毫秒.

所以我尝试使用objectMapper.setDateFormat哪个没有改变任何东西.

我目前的解决方法是:

ObjectMapper om = new ObjectMapper();

DateTimeFormatter dtf = new DateTimeFormatterBuilder()
    .appendInstant(0)
    .toFormatter();

JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeString(dtf.format(value));
    }
});

om.registerModule(jtm);
Run Code Online (Sandbox Code Playgroud)

我正在覆盖默认的序列化工具Instant.class.


有没有什么好办法使用一些配置参数来解决这个问题?

ZZ *_*Z 5 6

这是一些格式化字段的 Kotlin 代码Instant,因此它们不会包含毫秒,您可以使用自定义日期格式化程序

ObjectMapper().apply {
        val javaTimeModule = JavaTimeModule()
        javaTimeModule.addSerializer(Instant::class.java, Iso8601WithoutMillisInstantSerializer())
        registerModule(javaTimeModule)
        disable(WRITE_DATES_AS_TIMESTAMPS)
    }

private class Iso8601WithoutMillisInstantSerializer
        : InstantSerializer(InstantSerializer.INSTANCE, false, DateTimeFormatterBuilder().appendInstant(0).toFormatter())
Run Code Online (Sandbox Code Playgroud)


Pau*_*Pau 5

更新:

只需@JsonFormat在Instant属性上方添加带日期格式的注释即可。很简单

如果您有一个ObjectMapper,JavaTimeModule其次是:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
Run Code Online (Sandbox Code Playgroud)

如果您有一个带有Instant属性的类,则应添加@JsonFormat批注并放置不为毫秒的日期模式。就像下一个:

public static class TestDate {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "UTC")
    Instant instant;

    //getters & setters
}
Run Code Online (Sandbox Code Playgroud)

因此,如果将一个对象序列化为Json,它会完美地工作:

String json = mapper.writeValueAsString(testDate);
System.out.println(json); 
Run Code Online (Sandbox Code Playgroud)

输出量

{“即时”:“ 2016-11-10 06:03:06”}


旧答案。我不知道为什么,但无法正常工作:

您可以使用Jackson2ObjectMapperBuilder构建它。

您只需要添加所需的dateFormat。接下来会是这样:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

ObjectMapper mapper = Jackson2ObjectMapperBuilder
            .json()       
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) 
            .modules(new JavaTimeModule())
            .dateFormat(dateFormat)
            .build();
Run Code Online (Sandbox Code Playgroud)

  • 24 小时格式应为“yyyy-MM-dd HH:mm:ss”以避免混淆(am 和 pm 不属于此输出) (2认同)

use*_*814 5

这是一个替代方案,您可以在全局范围内进行设置,但是ZonedDateTime由于我们无法设置InstantJava时间模块随附的序列化程序的格式,因此需要与即时格式化程序一起使用。

您将不会看到使用分区日期时间即时的任何副作用,因为杰克逊分别序列化了区域ID,并且默认情况下处于禁用状态。因此从技术上讲,这类似于将格式化程序应用于Instant。

当以这种方式使用时,ZonedDateTime序列化程序将序列化委托给InstantBaseSerializer指定的自定义格式并使用。

@RunWith(JUnit4.class)
public class InstantNoMillisTest {

    private ObjectMapper objectMapper;

    @Before
    public void init() {
        JavaTimeModule module = new JavaTimeModule();
        ZonedDateTimeSerializer zonedDateTimeSerializer = new ZonedDateTimeSerializer(new DateTimeFormatterBuilder().appendInstant(0).toFormatter());
        module.addSerializer(ZonedDateTime.class, zonedDateTimeSerializer);
        module.addDeserializer(ZonedDateTime.class, InstantDeserializer.ZONED_DATE_TIME);

        objectMapper = Jackson2ObjectMapperBuilder.json()
                .modules(module)
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .build();
    }

    @Test
    public void serialize() throws IOException {
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        String noMillis = objectMapper.writeValueAsString(zonedDateTime);
        System.out.print(noMillis);
    }

    @Test
    public void deserialize() throws IOException {
        String dateTime = "\"2017-10-26T12:54:59Z\"";
        ZonedDateTime noMillis = objectMapper.readValue(dateTime, ZonedDateTime.class);
        System.out.print(noMillis);
    }
}
Run Code Online (Sandbox Code Playgroud)