AWS Spring 无法设置对象映射器
AWS Spring can't set object mapper
我试图在 spring MessageTemplate 上设置 jackson 序列化程序以发送使用 jacksonMapper 和 SQS/SNS 格式化的消息,问题是它一直在发送未格式化的消息,即使使用符号 @JsonProperty 或 @JsonFormat
这是我的配置:
@Configuration
class AwsMessagingConfigurationLocal(
@Value("${cloud.aws.region.static}") val region: String,
@Value("${cloud.aws.credentials.accessKey}") val accessKey: String,
@Value("${cloud.aws.credentials.secretKey}") val secretKey: String,
@Value("${cloud.aws.endpoint}") val endpoint: String
) {
@Bean
fun notificationMessageTemplate(): NotificationMessagingTemplate {
return NotificationMessagingTemplate(buildAmazonSNSAsync())
}
@Bean
fun queueMessagingTemplate(): QueueMessagingTemplate {
return QueueMessagingTemplate(buildAmazonSQSAsync())
}
@Bean
fun simpleMessageListenerContainerFactory(): SimpleMessageListenerContainerFactory {
val messageListenerContainerFactory = SimpleMessageListenerContainerFactory()
messageListenerContainerFactory.setAmazonSqs(buildAmazonSQSAsync())
return messageListenerContainerFactory
}
@Bean
fun queueMessageHandlerFactory(objectMapper: ObjectMapper): QueueMessageHandlerFactory {
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper.registerModule(JavaTimeModule())
val queueMessageHandlerFactory = QueueMessageHandlerFactory()
queueMessageHandlerFactory.messageConverters = listOf(messageConverter)
queueMessageHandlerFactory.setArgumentResolvers(listOf(NotificationMessageArgumentResolver(messageConverter)))
return queueMessageHandlerFactory
}
private fun buildAmazonSNSAsync(): AmazonSNSAsync {
return AmazonSNSAsyncClientBuilder.standard()
.withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(accessKey, secretKey)))
.build()
}
private fun buildAmazonSQSAsync(): AmazonSQSAsync {
return AmazonSQSAsyncClientBuilder.standard()
.withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(accessKey, secretKey)))
.build()
}
}
但是当我使用 LocalDateTime 发送对象时,即使使用 @JsonFormat,它仍然发送错误的格式:
data class Blob(
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
val timestamp: LocalDateTime
)
我制作了这个简单的调度函数来通过 SNS(主题)发送消息并连接一个队列来接收响应。
class Dispatcher(
private val private val notificationTemplate: NotificationMessagingTemplate
)
fun dispatch(blob: Blob) {
val header = mapOf("randon" to "message")
notificationTemplate.convertAndSend("topic", blob, header)
}
想要的结果:
\"timestamp\"=\"2021-11-26T19:18:46.905505\"
当前结果:
"timestamp\":{\"nano\":913070000,\"year\":2021,\"monthValue\":11,\"dayOfMonth\":26,\"hour\":19,\"minute\":18,\"second\":46,\"month\":\"NOVEMBER\",\"dayOfWeek\":\"FRIDAY\",\"dayOfYear\":330,\"chronology\":{\"calendarType\":\"iso8601\",\"id\":\"ISO\"}}
我对发生的事情一无所知。
PS。我也测试了SQS,结果也是一样
在 awspring 中搜索后,我发现默认设置了 SimpleMessageConverter,经过一些研究,我找到了在 sendAndConvert() 函数中设置自定义映射器的正确方法。这是配置:
@Bean
fun notificationMessageTemplate(objectMapper: ObjectMapper): NotificationMessagingTemplate {
// here we set the custom message converter
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper
// as we want to send it as a Json, we need to set the serialization to String
messageConverter.serializedPayloadClass = String::class.java
val notificationMessageTemplate = NotificationMessagingTemplate(buildAmazonSNSAsync())
// here is where we set the proper message converter
notificationMessageTemplate.messageConverter = messageConverter
return notificationMessageTemplate
}
@Bean
fun queueMessagingTemplate(objectMapper: ObjectMapper): QueueMessagingTemplate {
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper
messageConverter.serializedPayloadClass = String::class.java
val queueMessageConverter = QueueMessagingTemplate(buildAmazonSQSAsync())
queueMessageConverter.messageConverter = messageConverter
return queueMessageConverter
}
设置此映射器后,每个符号都可以正常工作。
结果如下:
\"timestamp\":\"2021-11-29T17:46:52Z\"
我试图在 spring MessageTemplate 上设置 jackson 序列化程序以发送使用 jacksonMapper 和 SQS/SNS 格式化的消息,问题是它一直在发送未格式化的消息,即使使用符号 @JsonProperty 或 @JsonFormat
这是我的配置:
@Configuration
class AwsMessagingConfigurationLocal(
@Value("${cloud.aws.region.static}") val region: String,
@Value("${cloud.aws.credentials.accessKey}") val accessKey: String,
@Value("${cloud.aws.credentials.secretKey}") val secretKey: String,
@Value("${cloud.aws.endpoint}") val endpoint: String
) {
@Bean
fun notificationMessageTemplate(): NotificationMessagingTemplate {
return NotificationMessagingTemplate(buildAmazonSNSAsync())
}
@Bean
fun queueMessagingTemplate(): QueueMessagingTemplate {
return QueueMessagingTemplate(buildAmazonSQSAsync())
}
@Bean
fun simpleMessageListenerContainerFactory(): SimpleMessageListenerContainerFactory {
val messageListenerContainerFactory = SimpleMessageListenerContainerFactory()
messageListenerContainerFactory.setAmazonSqs(buildAmazonSQSAsync())
return messageListenerContainerFactory
}
@Bean
fun queueMessageHandlerFactory(objectMapper: ObjectMapper): QueueMessageHandlerFactory {
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper.registerModule(JavaTimeModule())
val queueMessageHandlerFactory = QueueMessageHandlerFactory()
queueMessageHandlerFactory.messageConverters = listOf(messageConverter)
queueMessageHandlerFactory.setArgumentResolvers(listOf(NotificationMessageArgumentResolver(messageConverter)))
return queueMessageHandlerFactory
}
private fun buildAmazonSNSAsync(): AmazonSNSAsync {
return AmazonSNSAsyncClientBuilder.standard()
.withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(accessKey, secretKey)))
.build()
}
private fun buildAmazonSQSAsync(): AmazonSQSAsync {
return AmazonSQSAsyncClientBuilder.standard()
.withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(accessKey, secretKey)))
.build()
}
}
但是当我使用 LocalDateTime 发送对象时,即使使用 @JsonFormat,它仍然发送错误的格式:
data class Blob(
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
val timestamp: LocalDateTime
)
我制作了这个简单的调度函数来通过 SNS(主题)发送消息并连接一个队列来接收响应。
class Dispatcher(
private val private val notificationTemplate: NotificationMessagingTemplate
)
fun dispatch(blob: Blob) {
val header = mapOf("randon" to "message")
notificationTemplate.convertAndSend("topic", blob, header)
}
想要的结果:
\"timestamp\"=\"2021-11-26T19:18:46.905505\"
当前结果:
"timestamp\":{\"nano\":913070000,\"year\":2021,\"monthValue\":11,\"dayOfMonth\":26,\"hour\":19,\"minute\":18,\"second\":46,\"month\":\"NOVEMBER\",\"dayOfWeek\":\"FRIDAY\",\"dayOfYear\":330,\"chronology\":{\"calendarType\":\"iso8601\",\"id\":\"ISO\"}}
我对发生的事情一无所知。
PS。我也测试了SQS,结果也是一样
在 awspring 中搜索后,我发现默认设置了 SimpleMessageConverter,经过一些研究,我找到了在 sendAndConvert() 函数中设置自定义映射器的正确方法。这是配置:
@Bean
fun notificationMessageTemplate(objectMapper: ObjectMapper): NotificationMessagingTemplate {
// here we set the custom message converter
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper
// as we want to send it as a Json, we need to set the serialization to String
messageConverter.serializedPayloadClass = String::class.java
val notificationMessageTemplate = NotificationMessagingTemplate(buildAmazonSNSAsync())
// here is where we set the proper message converter
notificationMessageTemplate.messageConverter = messageConverter
return notificationMessageTemplate
}
@Bean
fun queueMessagingTemplate(objectMapper: ObjectMapper): QueueMessagingTemplate {
val messageConverter = MappingJackson2MessageConverter()
messageConverter.objectMapper = objectMapper
messageConverter.serializedPayloadClass = String::class.java
val queueMessageConverter = QueueMessagingTemplate(buildAmazonSQSAsync())
queueMessageConverter.messageConverter = messageConverter
return queueMessageConverter
}
设置此映射器后,每个符号都可以正常工作。
结果如下:
\"timestamp\":\"2021-11-29T17:46:52Z\"