apache / rocketmq-spring

Apache RocketMQ Spring Integration
https://rocketmq.apache.org/
Apache License 2.0
2.1k stars 895 forks source link

Jackson ObjectMapper Shadow serialization problem #40

Closed ChunMengLu closed 5 years ago

ChunMengLu commented 5 years ago
  1. Please describe the issue you observed:

Because Jackson's ObjectMapper configuration may be different in different services, such as Date, LocalDateTime will cause serialization to fail, as a dead letter.

由于在不同服务中,Jackson 的 ObjectMapper 配置可能不一样,比如 Date,LocalDateTime 会导致序列化失败,照成死信。

  1. Provide any additional detail on your proposed use case for this feature.

For Jackson message serialization and deserialization, it is recommended to extend the ObjectMapper to add a RocketmqObjectMapper. This avoids using the ObjectMapper in the service.

对于 Jackson 消息序列化和反序列化,建议 继承 ObjectMapper 添加 RocketmqObjectMapper, 从而避免使用服务里的 ObjectMapper。

walking98 commented 5 years ago

The current impl is designed to use the single/existing instance of ObjectMapper in whole server scope. It assumes the RMQ using the common ObjectMapper rather than a customized one. could you give an example for this?

ChunMengLu commented 5 years ago

The current impl is designed to use the single/existing instance of ObjectMapper in whole server scope. It assumes the RMQ using the common ObjectMapper rather than a customized one. could you give an example for this?

For example, service a producer datetime yyyy-MM-dd HH:mm:ss,service b consumer yyyy/MM/dd HH:mm:ss.

Cross-department is prone to such problems, and only if the service is abnormal, everyone will pay attention to it.

ChunMengLu commented 5 years ago

QQ群里已经有朋友反馈 JacksonFallbackConfiguration 已经影响到他们的项目里的配置了,这块建议要么添加 @ConditionalOnMissingBean,我觉得还是添加 RocketmqObjectMapper 更加靠谱。

There is already a friend feedback in the QQ group JacksonFallbackConfiguration has affected the configuration in their project. This suggestion either adds @ConditionalOnMissingBean, I think it is more reliable to add RocketmqObjectMapper.

dingdaoyi commented 5 years ago

添加了rocketmq-spring后原来配置的java8时间序列化失效了, "name": "ferfer", "type": 1, "startTime": { "hour": 0, "minute": 0, "second": 0, "nano": 0 }, "endTime": { "hour": 23, "minute": 0, "second": 0, "nano": 0 },

walking98 commented 5 years ago

@ChunMengLu I am not sure whether you can set your customized ObjectMapper in the rocketMQTemplate before using it. e.g. rocketMQTemplate.setObjectMapper(customizedObjectMapper); ... rocketMQTemplate.send(...);

Or would you like to provide a fix PR for further discussion ?

ChunMengLu commented 5 years ago

I first pr to #61 .

ChunMengLu commented 5 years ago

@walking98 先帮忙处理下 #61 。

The current issue of this issue means that the producer and the consumer are in different microservices. The configuration of the ObjectMapper bean of the group we have will be different. For example, the date format, when the date format on the two sides is different, it is not used. Special processing (Jackson time format, etc.) will deserialize failures to report exceptions. (当前的这个 issues 的意思是, 生产者和消费者在不同的微服务中,我们有的组的 ObjectMapper 的 bean 的配置会不一样,比如说日期格式,当2边有日期格式不一样,没有采用特殊处理时(Jackson 时间格式等)会反序列化失败报异常。)

walking98 commented 5 years ago

How about my previous proposal, "rocketMQTemplate.setObjectMapper(customizedObjectMapper);" ? does it work?

61 just adds a dependency, I can not figure out how it would resolve the issue, do you plan to add whole solution in the PR? @ChunMengLu

walking98 commented 5 years ago

61 has been merged.

wo8335224 commented 1 year ago

@Configuration public class RocketMQEnhanceConfig {     /*       解决RocketMQ Jackson不支持Java时间类型配置       源码参考:{@link org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration}      /     @Bean     @Primary     public RocketMQMessageConverter enhanceRocketMQMessageConverter(){         RocketMQMessageConverter converter = new RocketMQMessageConverter();         CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();         List messageConverterList = compositeMessageConverter.getConverters();         for (MessageConverter messageConverter : messageConverterList) {             if(messageConverter instanceof MappingJackson2MessageConverter){                 MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;                 ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();                 objectMapper.registerModules(new JavaTimeModule());             }         }         return converter;     } }