我在 Spring Boot 应用程序中格式化 Java 8 LocalDateTime 时遇到了一个小问题。使用“正常”日期我没有问题,但 LocalDateTime 字段转换为以下内容:
"startDate" : {
"year" : 2010,
"month" : "JANUARY",
"dayOfMonth" : 1,
"dayOfWeek" : "FRIDAY",
"dayOfYear" : 1,
"monthValue" : 1,
"hour" : 2,
"minute" : 2,
"second" : 0,
"nano" : 0,
"chronology" : {
"id" : "ISO",
"calendarType" : "iso8601"
}
}
虽然我想将其转换为:
"startDate": "2015-01-01"
我的代码如下所示:
@JsonFormat(pattern="yyyy-MM-dd")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
public LocalDateTime getStartDate() {
return startDate;
}
但是上述任何一个注释都不起作用,日期一直像上面一样格式化。欢迎提出建议!
更新:Spring Boot 2.x 不再需要此配置。我写了a more up to date answer here。
(这是 Spring Boot 2.x 之前的做法,可能对使用旧版本 Spring Boot 的人有用)
我终于找到了here怎么做。要修复它,我需要另一个依赖项:
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.4.0")
通过包含此依赖项,Spring 将自动为其注册转换器,如 here 所述。之后,您需要将以下内容添加到 application.properties:
spring.jackson.serialization.write_dates_as_timestamps=false
这将确保使用正确的转换器,并且日期将以 2016-03-16T13:56:39.492
的格式打印
只有在您想要更改日期格式时才需要注释。
我添加了 com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.6.1
依赖项并开始获取以下格式的日期:
"birthDate": [
2016,
1,
25,
21,
34,
55
]
这不是我想要的,但我越来越近了。然后我添加了以下内容
spring.jackson.serialization.write_dates_as_timestamps=false
到 application.properties 文件,它给了我我需要的正确格式。
"birthDate": "2016-01-25T21:34:55"
jackson-datatype-jsr310
依赖项时开箱即用。这应该是公认的答案。
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
在这里,它位于 Maven 中,拥有该属性,因此您可以在 Spring Boot 升级之间生存
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
@JsonSerialize(using = LocalDateTimeSerializer.class)
1) 依赖
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.8.8'
2)日期时间格式的注释。
public class RestObject {
private LocalDateTime timestamp;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public LocalDateTime getTimestamp() {
return timestamp;
}
}
3)弹簧配置。
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
System.out.println("Config is starting.");
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
}
写下这个答案也是对我的提醒。
我在这里结合了几个答案,最后我的答案是这样的。 (我使用的是 SpringBoot 1.5.7 和 Lombok 1.16.16)
@Data
public Class someClass {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime someDate;
}
DateTimeFormat
和其他人添加导入。
我找到了另一种解决方案,您可以将其转换为您想要的任何格式并应用于所有 LocalDateTime 数据类型,并且您不必在每个 LocalDateTime 数据类型上方指定 @JsonFormat。首先添加依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
添加以下bean:
@Configuration
public class Java8DateTimeConfiguration {
/**
* Customizing
* http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html
*
* Defining a @Bean of type Jackson2ObjectMapperBuilder will allow you to customize both default ObjectMapper and XmlMapper (used in MappingJackson2HttpMessageConverter and MappingJackson2XmlHttpMessageConverter respectively).
*/
@Bean
public Module jsonMapperJava8DateTimeModule() {
val bean = new SimpleModule();
bean.addDeserializer (ZonedDateTime.class, new JsonDeserializer<ZonedDateTime>() {
@Override
public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return ZonedDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
});
bean.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return LocalDateTime.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
});
bean.addSerializer(ZonedDateTime.class, new JsonSerializer<ZonedDateTime>() {
@Override
public void serialize(
ZonedDateTime zonedDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime));
}
});
bean.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
@Override
public void serialize(
LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime));
}
});
return bean;
}
}
在您的配置文件中添加以下内容:
@Import(Java8DateTimeConfiguration.class)
只要您使用 spring 创建的 objectMapper,这将序列化和反序列化所有属性 LocalDateTime 和 ZonedDateTime。
您获得的 ZonedDateTime 格式为:“2017-12-27T08:55:17.317+02:00[Asia/Jerusalem]”,LocalDateTime 为:“2017-12-27T09:05:30.523”
SimpleModule
扩展 Module
。 Module
是摘要。 val bean = new SimpleModule();
完美运行。
我正在使用 Spring Boot 2.1.8。我已经进口了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
其中包括 jackson-datatype-jsr310。
然后,我不得不添加这些注释
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("date")
LocalDateTime getDate();
它有效。 JSON 看起来像这样:
"date": "2020-03-09 17:55:00"
spring-boot-starter-web
时才需要包含 spring-boot-starter-json
。
这工作正常:
添加依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
添加注释:
@JsonFormat(pattern="yyyy-MM-dd")
现在,您必须获得正确的格式。
要使用对象映射器,您需要注册 JavaTime
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
这对我有用。
我在我的 DTO 中定义了birthDate 字段,如下所述:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthDate;
在我的请求正文中,我以以下格式传递了birthDate:
{
"birthDate": "2021-06-03 00:00:00"
}
@JsonFormat(pattern="yyyy-MM-dd HH:mm")
确实有效。这不适用于 yyyy-MM-dd hh:mm
如前所述,spring-boot 将获取您需要的所有内容(对于 web 和 webflux starter)。
但更好的是 - 您不需要自己注册任何模块。看看here。由于 @SpringBootApplication
在后台使用 @EnableAutoConfiguration
,这意味着 JacksonAutoConfiguration
将自动添加到上下文中。现在,如果您查看 JacksonAutoConfiguration
内部,您将看到:
private void configureModules(Jackson2ObjectMapperBuilder builder) {
Collection<Module> moduleBeans = getBeans(this.applicationContext,
Module.class);
builder.modulesToInstall(moduleBeans.toArray(new Module[0]));
}
This fella 将在初始化过程中被调用,并将获取它可以在类路径中找到的所有模块。 (我使用 Spring Boot 2.1)
这对我有用。
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
public Class someClass {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime sinceDate;
}
我使用的是 Springboot 2.0.6,由于某种原因,应用程序 yml 更改不起作用。而且我还有更多的要求。
我尝试创建 ObjectMapper 并将其标记为 Primary 但 spring boot 抱怨我已经将 jacksonObjectMapper 标记为 Primary!
所以这就是我所做的。我对内部映射器进行了更改。
我的序列化器和反序列化器很特别——它们处理'dd/MM/YYYY';并且在反序列化时 - 它会尽力使用 3-4 种流行格式来确保我有一些 LocalDate。
@Autowired
ObjectMapper mapper;
@PostConstruct
public ObjectMapper configureMapper() {
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.configure(MapperFeature.ALLOW_COERCION_OF_SCALARS, true);
mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
module.addSerializer(LocalDate.class, new LocalDateSerializer());
mapper.registerModule(module);
return mapper;
}
@JsonDeserialize(using= LocalDateDeserializer.class)
不适用于以下依赖项。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version> 2.9.6</version>
</dependency>
我使用下面的代码转换器将日期反序列化为 java.sql.Date
。
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@SuppressWarnings("UnusedDeclaration")
@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<java.time.LocalDate, java.sql.Date> {
@Override
public java.sql.Date convertToDatabaseColumn(java.time.LocalDate attribute) {
return attribute == null ? null : java.sql.Date.valueOf(attribute);
}
@Override
public java.time.LocalDate convertToEntityAttribute(java.sql.Date dbData) {
return dbData == null ? null : dbData.toLocalDate();
}
}
添加
group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.8.8'
进入 gradle 编译块
并在 application.yml
文件中
spring:
jackson:
serialization:
write_dates_as_timestamps: false
如果您使用的是 application.properties
文件,请添加以下内容
spring.jackson.serialization.write_dates_as_timestamps=false
如果您想应用自定义格式,您可以应用注释
@JsonFormat(pattern = "yyyy-MMMM-dd hh:mm:ss")
private LocalDateTime date;
它开始对我很好
以下注释对我有用
@JsonSerialize(using = LocalDateSerializer.class) and
@JsonFormat(pattern="yyyy-MM-dd")
只需使用:
@JsonFormat(pattern="10/04/2019")
或者您可以随意使用模式,例如:('-' in place of '/')
@JsonSerialize(using = LocalDateTimeSerializer.class)
...application.properties
条目可能会更好。@JsonSerialize
注释才能使其正常工作。@JsonSerialize(using = LocalDateSerializer.class)
和@JsonFormat(pattern="yyyy-MM-dd")
,没有新的依赖项和属性。