在 Spring 引导中使用 Jackson 反序列化 Date 对象
Deserialize Date object with Jackson in Spring boot
我的数据对象 returns 数据为 1604571544010
,我需要更具可读性的内容。
我尝试了很多东西,但似乎没有任何效果,我怀疑 Jackson
或 spring 版本有问题。
我尝试在application.properties
中设置数据格式
我还尝试了 baeldung
中的所有全局配置
Pom.xml
<jackson.version>2.11.3</jackson.version>
<jackson.databind.version>2.11.3</jackson.databind.version>
<jackson.mapper.version>1.9.13</jackson.mapper.version>
<spring.boot.version>2.1.17.RELEASE</spring.boot.version>
<spring.version>5.1.18.RELEASE</spring.version>
WebConfig
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder()
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
return new Jackson2ObjectMapperBuilder().indentOutput(true).dateFormat(sdf);
}
DTO
@JsonProperty
public Date getStartDateTime()
{
return startDateTime;
}
使用@JsonComponent
。任何 Date
类型都将使用此自定义序列化程序进行序列化。
@JsonComponent
class DateSerializer extends JsonSerializer<Date> {
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
public DateSerializer() {
this(null);
}
public DateSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(
Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(sdf.format(value));
}
}
不使用@JsonComponent
在 WebConfiguration
中注册自定义序列化程序。
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
SimpleModule m = new SimpleModule();
m.addSerializer(Date.class, new DateSerializer());
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().modules(m);
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
或者如果要标记每个字段
@JsonSerialize(using = DateSerializer.class)
public Date getStartDateTime()
{
return startDateTime;
}
您可以在 application.properties 中添加 属性 spring.jackson.date-format
以提供 java.util.Date
的特定日期格式。
例如。 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
唯一对我有用的全局设置是 ObjectMapper
@Bean
@Primary
public ObjectMapper objectMapper()
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
final ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(sdf);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
return mapper;
}
全局解决方案:
@Slf4j
@JsonComponent
public class CustomDateDeserializer extends StdDeserializer<Date> {
private static final long serialVersionUID = 1L;
private final DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ"))
.toFormatter();
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String date = jsonparser.getText();
//if(date == null || date.isBlank()) return null;
if (NumberUtils.isParsable(date)) {
try {
return new Date(Long.parseLong(date));
} catch (Exception e) {
log.trace("Long Unparseable date: \"" + date + "\"");
throw new RuntimeException("LongUnparseable date: \"" + date + "\"");
}
}
try {
LocalDateTime dateToConvert = LocalDateTime.parse(jsonparser.getText(), dateFormatter);
return java.sql.Timestamp.valueOf(dateToConvert);
} catch (Exception e) {
log.error("Error parsing date: \"" + date + "\" : ", e);
throw new RuntimeException("Unparseable date: \"" + date + "\"");
}
}
}
`
这与 Chayne 发布的解决方案相同,但使用 DateTimeFormatter 而不是 SimpleDateFormat,因为 DateTimeFormatter 是线程安全的。
我的数据对象 returns 数据为 1604571544010
,我需要更具可读性的内容。
我尝试了很多东西,但似乎没有任何效果,我怀疑 Jackson
或 spring 版本有问题。
我尝试在application.properties
中设置数据格式我还尝试了 baeldung
中的所有全局配置Pom.xml
<jackson.version>2.11.3</jackson.version>
<jackson.databind.version>2.11.3</jackson.databind.version>
<jackson.mapper.version>1.9.13</jackson.mapper.version>
<spring.boot.version>2.1.17.RELEASE</spring.boot.version>
<spring.version>5.1.18.RELEASE</spring.version>
WebConfig
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder()
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
return new Jackson2ObjectMapperBuilder().indentOutput(true).dateFormat(sdf);
}
DTO
@JsonProperty
public Date getStartDateTime()
{
return startDateTime;
}
使用@JsonComponent
。任何 Date
类型都将使用此自定义序列化程序进行序列化。
@JsonComponent
class DateSerializer extends JsonSerializer<Date> {
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
public DateSerializer() {
this(null);
}
public DateSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(
Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(sdf.format(value));
}
}
不使用@JsonComponent
在 WebConfiguration
中注册自定义序列化程序。
@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
SimpleModule m = new SimpleModule();
m.addSerializer(Date.class, new DateSerializer());
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().modules(m);
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
或者如果要标记每个字段
@JsonSerialize(using = DateSerializer.class)
public Date getStartDateTime()
{
return startDateTime;
}
您可以在 application.properties 中添加 属性 spring.jackson.date-format
以提供 java.util.Date
的特定日期格式。
例如。 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
唯一对我有用的全局设置是 ObjectMapper
@Bean
@Primary
public ObjectMapper objectMapper()
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
final ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(sdf);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
return mapper;
}
全局解决方案:
@Slf4j
@JsonComponent
public class CustomDateDeserializer extends StdDeserializer<Date> {
private static final long serialVersionUID = 1L;
private final DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssZ"))
.toFormatter();
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String date = jsonparser.getText();
//if(date == null || date.isBlank()) return null;
if (NumberUtils.isParsable(date)) {
try {
return new Date(Long.parseLong(date));
} catch (Exception e) {
log.trace("Long Unparseable date: \"" + date + "\"");
throw new RuntimeException("LongUnparseable date: \"" + date + "\"");
}
}
try {
LocalDateTime dateToConvert = LocalDateTime.parse(jsonparser.getText(), dateFormatter);
return java.sql.Timestamp.valueOf(dateToConvert);
} catch (Exception e) {
log.error("Error parsing date: \"" + date + "\" : ", e);
throw new RuntimeException("Unparseable date: \"" + date + "\"");
}
}
}
`
这与 Chayne 发布的解决方案相同,但使用 DateTimeFormatter 而不是 SimpleDateFormat,因为 DateTimeFormatter 是线程安全的。