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\"