Jackson SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 未在 spring 中关闭时间戳
Jackson SerializationFeature.WRITE_DATES_AS_TIMESTAMPS not turning off timestamps in spring
经过大量搜索后,我找到了如何在我的@RestController 中转换为 JSON 响应时阻止 java.util.Date 字段被序列化为时间戳。
但是我无法让它工作。我找到的所有帖子都说要禁用 Jackson objet 映射器的 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 功能。所以我写了下面的代码:
public class MVCConfig {
@Autowired
Jackson2ObjectMapperFactoryBean objectMapper;
@PostConstruct
public void postConstruct() {
this.objectMapper.setFeaturesToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
据我了解,配置也是一个 bean,因此在对象映射器中自动连接以设置其他属性应该有效。我使用了断点,这个设置看起来一切都很好。
然而,当我在对 http 查询的响应中使用 java.util.Date 属性 序列化一个 bean 时,我仍然得到一个时间戳。
有谁知道为什么这不起作用?这让我难住了!
是的,要挂钩并更改转换器正在使用的对象映射器,您应该执行类似
的操作
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
this.configure(com.fasterxml.jackson.databind.SerializationFeature.
WRITE_DATES_AS_TIMESTAMPS, false);
}
}
在你的 MVCConfig
@Bean
public ObjectMapper jacksonObjectMapper() {
return new CustomObjectMapper();
}
@Bean
public SerializationConfig serializationConfig() {
return jacksonObjectMapper().getSerializationConfig();
}
经过一番折腾,我发现下面的代码解决了这个问题:
public class MVCConfig extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
break;
}
}
}
}
我不确定是否有更简单的方法来访问 Jackson MVC 消息转换器并对其进行配置。但这对我有用。
是的,我同意@Feyyaz:将配置添加到 properties/yml 文件是配置默认的上下文(反)序列化器的方法,当这超出您的控制并且只能由Spring 上下文。
有关详细信息,请参阅 Spring 文档的这一部分:
原始 link 删除情况下的引用:
79.3 Customize the Jackson ObjectMapper
Spring MVC (client and server side) uses HttpMessageConverters
to negotiate content conversion in an HTTP exchange. If Jackson is on the classpath, you already get the default converter(s) provided by Jackson2ObjectMapperBuilder
, an instance of which is auto-configured for you.
The ObjectMapper
(or XmlMapper
for Jackson XML converter) instance (created by default) has the following customized properties:
MapperFeature.DEFAULT_VIEW_INCLUSION
is disabled
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabled
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
is disabled
Spring Boot also has some features to make it easier to customize this behavior.
You can configure the ObjectMapper
and XmlMapper
instances by using the environment. Jackson provides an extensive suite of simple on/off features that can be used to configure various aspects of its processing. These features are described in six enums:
Enum
Property
Values
com.fasterxml.jackson.databind.DeserializationFeature
spring.jackson.deserialization.<feature_name>
true
, false
com.fasterxml.jackson.core.JsonGenerator.Feature
spring.jackson.generator.<feature_name>
true
, false
com.fasterxml.jackson.databind.MapperFeature
spring.jackson.mapper.<feature_name>
true
, false
com.fasterxml.jackson.core.JsonParser.Feature
spring.jackson.parser.<feature_name>
true
, false
com.fasterxml.jackson.databind.SerializationFeature
spring.jackson.serialization.<feature_name>
true
, false
com.fasterxml.jackson.annotation.JsonInclude.Include
spring.jackson.default-property-inclusion
always
, non_null
, non_absent
, non_default
, non_empty
For example, to enable pretty print, set spring.jackson.serialization.indent_output=true
. Note that, thanks to the use of relaxed binding, the case of indent_output
does not have to match the case of the corresponding enum constant, which is INDENT_OUTPUT
.
This environment-based configuration is applied to the auto-configured Jackson2ObjectMapperBuilder
bean and applies to any mappers created by using the builder, including the auto-configured ObjectMapper
bean.
The context’s Jackson2ObjectMapperBuilder
can be customized by one or more Jackson2ObjectMapperBuilderCustomizer
beans. Such customizer beans can be ordered (Boot’s own customizer has an order of 0), letting additional customization be applied both before and after Boot’s customization.
Any beans of type com.fasterxml.jackson.databind.Module
are automatically registered with the auto-configured Jackson2ObjectMapperBuilder
and are applied to any ObjectMapper
instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.
If you want to replace the default ObjectMapper
completely, either define a @Bean
of that type and mark it as @Primary
or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder
@Bean
. Note that, in either case, doing so disables all auto-configuration of the ObjectMapper
.
If you provide any @Beans
of type MappingJackson2HttpMessageConverter
, they replace the default value in the MVC configuration. Also, a convenience bean of type HttpMessageConverters
is provided (and is always available if you use the default MVC configuration). It has some useful methods to access the default and user-enhanced message converters.
See the “Section 79.4, “Customize the @ResponseBody Rendering”” section and the WebMvcAutoConfiguration
source code for more details.
示例:
spring:
jackson:
default-property-inclusion: non_null # to exclude null in json serialization
serialization:
write-dates-as-timestamps: true # write milliseconds since epoch in the final json
或者:
spring.jackson.default-property-inclusion: non_null # to exclude null in json serialization
spring.jackson.serialization.write-dates-as-timestamps: true # write milliseconds since epoch in the final json
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
如果您在 spring 启动时使用 swagger,并且您的日期是
没有帮助,下面的解决方案对我有用。将它添加到你的 class 注释 @SpringBootApplication:
@Autowired
private RequestMappingHandlerAdapter handlerAdapter;
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
handlerAdapter
.getMessageConverters()
.stream()
.forEach(c -> {
if (c instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) c;
ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
});
}
实际问题:SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 值未从 spring 配置文件中读取,需要将其设置为 false 以便在序列化时隐藏长值。
经过大量搜索后,我找到了如何在我的@RestController 中转换为 JSON 响应时阻止 java.util.Date 字段被序列化为时间戳。
但是我无法让它工作。我找到的所有帖子都说要禁用 Jackson objet 映射器的 SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 功能。所以我写了下面的代码:
public class MVCConfig {
@Autowired
Jackson2ObjectMapperFactoryBean objectMapper;
@PostConstruct
public void postConstruct() {
this.objectMapper.setFeaturesToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
据我了解,配置也是一个 bean,因此在对象映射器中自动连接以设置其他属性应该有效。我使用了断点,这个设置看起来一切都很好。
然而,当我在对 http 查询的响应中使用 java.util.Date 属性 序列化一个 bean 时,我仍然得到一个时间戳。
有谁知道为什么这不起作用?这让我难住了!
是的,要挂钩并更改转换器正在使用的对象映射器,您应该执行类似
的操作public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
this.configure(com.fasterxml.jackson.databind.SerializationFeature.
WRITE_DATES_AS_TIMESTAMPS, false);
}
}
在你的 MVCConfig
@Bean
public ObjectMapper jacksonObjectMapper() {
return new CustomObjectMapper();
}
@Bean
public SerializationConfig serializationConfig() {
return jacksonObjectMapper().getSerializationConfig();
}
经过一番折腾,我发现下面的代码解决了这个问题:
public class MVCConfig extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
break;
}
}
}
}
我不确定是否有更简单的方法来访问 Jackson MVC 消息转换器并对其进行配置。但这对我有用。
是的,我同意@Feyyaz:将配置添加到 properties/yml 文件是配置默认的上下文(反)序列化器的方法,当这超出您的控制并且只能由Spring 上下文。
有关详细信息,请参阅 Spring 文档的这一部分:
原始 link 删除情况下的引用:
79.3 Customize the Jackson ObjectMapper
Spring MVC (client and server side) uses
HttpMessageConverters
to negotiate content conversion in an HTTP exchange. If Jackson is on the classpath, you already get the default converter(s) provided byJackson2ObjectMapperBuilder
, an instance of which is auto-configured for you. TheObjectMapper
(orXmlMapper
for Jackson XML converter) instance (created by default) has the following customized properties:
MapperFeature.DEFAULT_VIEW_INCLUSION
is disabledDeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
is disabledSerializationFeature.WRITE_DATES_AS_TIMESTAMPS
is disabledSpring Boot also has some features to make it easier to customize this behavior. You can configure the
ObjectMapper
andXmlMapper
instances by using the environment. Jackson provides an extensive suite of simple on/off features that can be used to configure various aspects of its processing. These features are described in six enums:
Enum Property Values com.fasterxml.jackson.databind.DeserializationFeature
spring.jackson.deserialization.<feature_name>
true
,false
com.fasterxml.jackson.core.JsonGenerator.Feature
spring.jackson.generator.<feature_name>
true
,false
com.fasterxml.jackson.databind.MapperFeature
spring.jackson.mapper.<feature_name>
true
,false
com.fasterxml.jackson.core.JsonParser.Feature
spring.jackson.parser.<feature_name>
true
,false
com.fasterxml.jackson.databind.SerializationFeature
spring.jackson.serialization.<feature_name>
true
,false
com.fasterxml.jackson.annotation.JsonInclude.Include
spring.jackson.default-property-inclusion
always
,non_null
,non_absent
,non_default
,non_empty
For example, to enable pretty print, set
spring.jackson.serialization.indent_output=true
. Note that, thanks to the use of relaxed binding, the case ofindent_output
does not have to match the case of the corresponding enum constant, which isINDENT_OUTPUT
.This environment-based configuration is applied to the auto-configured
Jackson2ObjectMapperBuilder
bean and applies to any mappers created by using the builder, including the auto-configuredObjectMapper
bean.The context’s
Jackson2ObjectMapperBuilder
can be customized by one or moreJackson2ObjectMapperBuilderCustomizer
beans. Such customizer beans can be ordered (Boot’s own customizer has an order of 0), letting additional customization be applied both before and after Boot’s customization.Any beans of type
com.fasterxml.jackson.databind.Module
are automatically registered with the auto-configuredJackson2ObjectMapperBuilder
and are applied to anyObjectMapper
instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.If you want to replace the default
ObjectMapper
completely, either define a@Bean
of that type and mark it as@Primary
or, if you prefer the builder-based approach, define aJackson2ObjectMapperBuilder
@Bean
. Note that, in either case, doing so disables all auto-configuration of theObjectMapper
. If you provide any@Beans
of typeMappingJackson2HttpMessageConverter
, they replace the default value in the MVC configuration. Also, a convenience bean of typeHttpMessageConverters
is provided (and is always available if you use the default MVC configuration). It has some useful methods to access the default and user-enhanced message converters.See the “Section 79.4, “Customize the @ResponseBody Rendering”” section and the
WebMvcAutoConfiguration
source code for more details.
示例:
spring:
jackson:
default-property-inclusion: non_null # to exclude null in json serialization
serialization:
write-dates-as-timestamps: true # write milliseconds since epoch in the final json
或者:
spring.jackson.default-property-inclusion: non_null # to exclude null in json serialization
spring.jackson.serialization.write-dates-as-timestamps: true # write milliseconds since epoch in the final json
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
如果您在 spring 启动时使用 swagger,并且您的日期是 没有帮助,下面的解决方案对我有用。将它添加到你的 class 注释 @SpringBootApplication:
@Autowired
private RequestMappingHandlerAdapter handlerAdapter;
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
handlerAdapter
.getMessageConverters()
.stream()
.forEach(c -> {
if (c instanceof MappingJackson2HttpMessageConverter) {
MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) c;
ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
});
}
实际问题:SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 值未从 spring 配置文件中读取,需要将其设置为 false 以便在序列化时隐藏长值。