如何在 Spring-AMQP 中使用 Jackson2JsonMessageConverter 处理内容类型 null
How do I handle content-type null with Jackson2JsonMessageConverter in Spring-AMQP
如果 it's not one problem, ... 我似乎已经解决了之前的 2 个问题,但现在当 运行 在测试上下文之外时,我看到了一个站立的应用程序。
o.s.a.s.c.Jackson2JsonMessageConverter : Could not convert incoming message with content-type [null], 'json' keyword missing.
和以前一样,这条消息看起来很清楚。哎呀,事情甚至在独立测试上下文中工作,但是当 运行 在独立服务器中时,代码似乎采用了不同的路径并且由于相同的原因失败,但通过不同的组件。
@Configuration
open class MessagingConfig {
@Bean
open fun jackson2Json(om: ObjectMapper): SmartMessageConverter {
return Jackson2JsonMessageConverter(om)
}
@Bean
open fun mappingJackson2(om: ObjectMapper): MappingJackson2MessageConverter {
val mc = MappingJackson2MessageConverter()
mc.objectMapper = om
return mc
}
@Bean
open fun defaultMessageHandlerMethodFactory(jackson: MappingJackson2MessageConverter): DefaultMessageHandlerMethodFactory {
val factory = DefaultMessageHandlerMethodFactory()
factory.setMessageConverter(jackson)
return factory
}
@Bean
open fun builder(): Jackson2ObjectMapperBuilderCustomizer {
return Jackson2ObjectMapperBuilderCustomizer {
it.modules(JavaTimeModule(), KotlinModule())
it.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
}
}
@Configuration
open class RabbitConfigurer(val dmhmf: DefaultMessageHandlerMethodFactory) : RabbitListenerConfigurer {
override fun configureRabbitListeners(registrar: RabbitListenerEndpointRegistrar?) {
registrar?.messageHandlerMethodFactory = dmhmf
}
}
}
根据AbstractJackson2MessageConverter
中的逻辑,需要contentType
AMQP 属性:
MessageProperties properties = message.getMessageProperties();
if (properties != null) {
String contentType = properties.getContentType();
if (contentType != null && contentType.contains(this.supportedContentType.getSubtype())) {
我认为我们需要对此组件进行改进,不要对它严格要求。与我们可以通过其对 MappingJackson2MessageConverter
执行的操作相同:
/**
* Whether this converter should convert messages for which no content type
* could be resolved through the configured
* {@link org.springframework.messaging.converter.ContentTypeResolver}.
* <p>A converter can configured to be strict only when a
* {@link #setContentTypeResolver contentTypeResolver} is configured and the
* list of {@link #getSupportedMimeTypes() supportedMimeTypes} is not be empty.
* <p>When this flag is set to {@code true}, {@link #supportsMimeType(MessageHeaders)}
* will return {@code false} if the {@link #setContentTypeResolver contentTypeResolver}
* is not defined or if no content-type header is present.
*/
public void setStrictContentTypeMatch(boolean strictContentTypeMatch) {
默认为 false
。
只有解决遗漏 contentType
问题的方法,但仍继续进行 JSON 消息转换,我看到自定义 org.springframework.amqp.support.converter.AbstractMessageConverter
实现,您可以在其中组合 Jackson2JsonMessageConverter
逻辑和不关心错过contentType
属性.
随时针对 Spring AMQP 提出问题以改进 AbstractJackson2MessageConverter
!
您可以将 MessagePostprocessor
添加到容器工厂以使用 content_id 属性 增强消息。
factory.setAfterReceivePostProcessors(m -> {
m.getMessageProperties().setContentId("application/json");
return m;
}
如果 it's not one problem,
o.s.a.s.c.Jackson2JsonMessageConverter : Could not convert incoming message with content-type [null], 'json' keyword missing.
和以前一样,这条消息看起来很清楚。哎呀,事情甚至在独立测试上下文中工作,但是当 运行 在独立服务器中时,代码似乎采用了不同的路径并且由于相同的原因失败,但通过不同的组件。
@Configuration
open class MessagingConfig {
@Bean
open fun jackson2Json(om: ObjectMapper): SmartMessageConverter {
return Jackson2JsonMessageConverter(om)
}
@Bean
open fun mappingJackson2(om: ObjectMapper): MappingJackson2MessageConverter {
val mc = MappingJackson2MessageConverter()
mc.objectMapper = om
return mc
}
@Bean
open fun defaultMessageHandlerMethodFactory(jackson: MappingJackson2MessageConverter): DefaultMessageHandlerMethodFactory {
val factory = DefaultMessageHandlerMethodFactory()
factory.setMessageConverter(jackson)
return factory
}
@Bean
open fun builder(): Jackson2ObjectMapperBuilderCustomizer {
return Jackson2ObjectMapperBuilderCustomizer {
it.modules(JavaTimeModule(), KotlinModule())
it.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
}
}
@Configuration
open class RabbitConfigurer(val dmhmf: DefaultMessageHandlerMethodFactory) : RabbitListenerConfigurer {
override fun configureRabbitListeners(registrar: RabbitListenerEndpointRegistrar?) {
registrar?.messageHandlerMethodFactory = dmhmf
}
}
}
根据AbstractJackson2MessageConverter
中的逻辑,需要contentType
AMQP 属性:
MessageProperties properties = message.getMessageProperties();
if (properties != null) {
String contentType = properties.getContentType();
if (contentType != null && contentType.contains(this.supportedContentType.getSubtype())) {
我认为我们需要对此组件进行改进,不要对它严格要求。与我们可以通过其对 MappingJackson2MessageConverter
执行的操作相同:
/**
* Whether this converter should convert messages for which no content type
* could be resolved through the configured
* {@link org.springframework.messaging.converter.ContentTypeResolver}.
* <p>A converter can configured to be strict only when a
* {@link #setContentTypeResolver contentTypeResolver} is configured and the
* list of {@link #getSupportedMimeTypes() supportedMimeTypes} is not be empty.
* <p>When this flag is set to {@code true}, {@link #supportsMimeType(MessageHeaders)}
* will return {@code false} if the {@link #setContentTypeResolver contentTypeResolver}
* is not defined or if no content-type header is present.
*/
public void setStrictContentTypeMatch(boolean strictContentTypeMatch) {
默认为 false
。
只有解决遗漏 contentType
问题的方法,但仍继续进行 JSON 消息转换,我看到自定义 org.springframework.amqp.support.converter.AbstractMessageConverter
实现,您可以在其中组合 Jackson2JsonMessageConverter
逻辑和不关心错过contentType
属性.
随时针对 Spring AMQP 提出问题以改进 AbstractJackson2MessageConverter
!
您可以将 MessagePostprocessor
添加到容器工厂以使用 content_id 属性 增强消息。
factory.setAfterReceivePostProcessors(m -> {
m.getMessageProperties().setContentId("application/json");
return m;
}