Spring Boot在哪里定义默认的JSON日期(即LocalDateTime)格式?

时间:2017-12-21 22:20:07

标签: spring spring-mvc spring-boot jackson

使用Spring Boot创建一个返回JSON有效负载的REST服务时,Java 8的LocalDateTime被序列化。在将对象编组到字符串时,(大概)Jackson应用的格式字符串(即模式)在哪里,我在哪里可以找到应用该格式的Spring Boot中的默认配置(即设置格式化程序)?

(注意:我可以在有效负载中看到格式化的日期,而不是时间戳。)

1 个答案:

答案 0 :(得分:0)

Jackson2ObjectMapperBuilderregisterWellKnownModulesIfAvailable方法中执行非常棘手的逻辑,用于注册多个模块。特别是对于java 8时间:

// Java 8 java.time package present?
if (ClassUtils.isPresent("java.time.LocalDate", this.moduleClassLoader)) {
    try {
        Class<? extends Module> javaTimeModule = (Class<? extends Module>)
                ClassUtils.forName("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", this.moduleClassLoader);
        objectMapper.registerModule(BeanUtils.instantiateClass(javaTimeModule));
    }
    catch (ClassNotFoundException ex) {
        // jackson-datatype-jsr310 not available
    }
}

因此,如果您的应用程序依赖jackson-datatype-jsr310模块spring将默默注册它。因此,您将从此模块为java时间类型提供专用的序列化器/反序列化器。你对LocalDateTimeSerializer感兴趣。正如您所看到的,序列化逻辑依赖于useTimestamp,在您的情况下返回false,因此我们转移到else分支。默认情况下,_formatter为空,使用的_defaultFormatter()DateTimeFormatter.ISO_LOCAL_DATE_TIME。如果要将日期序列化为字符串,或者通过从if方法返回true来使用useTimestamp分支中的序列化逻辑,则可以通过提供自定义格式化程序轻松更新此行为。

@Override
public void serialize(LocalDateTime value, JsonGenerator g, SerializerProvider provider)
    throws IOException
{
    if (useTimestamp(provider)) {
        g.writeStartArray();
        g.writeNumber(value.getYear());
        g.writeNumber(value.getMonthValue());
        g.writeNumber(value.getDayOfMonth());
        g.writeNumber(value.getHour());
        g.writeNumber(value.getMinute());
        if (value.getSecond() > 0 || value.getNano() > 0) {
            g.writeNumber(value.getSecond());
            if(value.getNano() > 0) {
                if (provider.isEnabled(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS))
                    g.writeNumber(value.getNano());
                else
                    g.writeNumber(value.get(ChronoField.MILLI_OF_SECOND));
            }
        }
        g.writeEndArray();
    } else {
        DateTimeFormatter dtf = _formatter;
        if (dtf == null) {
            dtf = _defaultFormatter();
        }
        g.writeString(value.format(dtf));
    }
}

// since 2.7: TODO in 2.8; change to use per-type defaulting
protected DateTimeFormatter _defaultFormatter() {
    return DateTimeFormatter.ISO_LOCAL_DATE_TIME;
}

protected boolean useTimestamp(SerializerProvider provider) {
    if (_useTimestamp != null) {
        return _useTimestamp.booleanValue();
    }
    // assume that explicit formatter definition implies use of textual format
    if (_formatter != null) { 
        return false;
    }
    return provider.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}