序文
遭遇した開発プロセスの問題のバーストの前にrabbitmq template
メッセージを送信し、時間内にメッセージ本体が8時間以下、現在の時間よりも、これは問題領域を見ています。
なぜそれについて話がです。
以下のように設定する前に、次のとおりです。
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
template.setMandatory(true);
...
return template;
}
VOメッセージに送り出さこれです:
@Data
public class TestVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date testDate;
}
その後、問題は、メッセージ本文、現在の8時間の時間よりも短い時間です。
{ "testDate": "2019年12月27日午前5時45分26秒"}
理由
使用RabbitMQのテンプレートがあるように、我々は以下のとおりです。
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private RedisRepository redisRepository;
/**
* 发送消息
* @param exchange 交换机名称
* @param routingKey 路由键
* @param msgMbject 消息体,无需序列化,会自动序列化为json
*/
public void send(String exchange, String routingKey, final Object msgMbject) {
CorrelationData correlationData = new CorrelationData(GUID.generate());
CachedMqMessageForConfirm cachedMqMessageForConfirm = new CachedMqMessageForConfirm(exchange, routingKey, msgMbject);
redisRepository.saveCacheMessageForConfirms(correlationData,cachedMqMessageForConfirm);
//核心代码:这里,发送出去的msgObject其实就是一个vo或者dto,rabbitmqTemplate会自动帮我们转为json
rabbitTemplate.convertAndSend(exchange,routingKey,msgMbject,correlationData);
}
私はコメントで説明し、変換がジャクソンは自動的に変換を行いますRabbitMQのです。
ソースは、調べるためにフォローアップすることができます:
org.springframework.amqp.rabbit.core.RabbitTemplate#convertAndSend
@Override
public void convertAndSend(String exchange, String routingKey, final Object object,
@Nullable CorrelationData correlationData) throws AmqpException {
// 这里调用了convertMessageIfNecessary(object)
send(exchange, routingKey, convertMessageIfNecessary(object), correlationData);
}
コールconvertMessageIfNessary:
protected Message convertMessageIfNecessary(final Object object) {
if (object instanceof Message) {
return (Message) object;
}
// 获取消息转换器
return getRequiredMessageConverter().toMessage(object, new MessageProperties());
}
メッセージコードコンバータを取得する次のとおりです。
private MessageConverter getRequiredMessageConverter() throws IllegalStateException {
MessageConverter converter = getMessageConverter();
if (converter == null) {
throw new AmqpIllegalStateException(
"No 'messageConverter' specified. Check configuration of RabbitTemplate.");
}
return converter;
}
getMessageConverterは、フィールドrabbitmqTemplateクラスを取得することです。
public MessageConverter getMessageConverter() {
return this.messageConverter;
}
それは割り当てを実行することができる場所を私たちは見るだけ。
その後、私はそれを考える、それが私たちのビジネスコードの割り当てであります:
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
// 下面这里赋值了。。。差点搞忘了
template.setMessageConverter(new Jackson2JsonMessageConverter());
template.setMandatory(true);
return template;
}
とにかく、それは、一般的には、送信する前に、当社のカスタムメッセージを変換messageConverter rabbitmqTemplateの使用です。
タイムゾーンの問題、良好な再現、ソースコード:
https://gitee.com/ckl111/all-simple-demo-in-work/tree/master/jackson-demo
@Data
public class TestVO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date testDate;
}
テストコード:
@org.junit.Test
public void normal() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
TestVO vo = new TestVO();
vo.setTestDate(new Date());
String value = mapper.writeValueAsString(vo);
System.out.println(value);
}
出力:
{ "testDate": "2019年12月27日午前5時45分26秒"}
ソリューション
デフォルトゾーンの設定をする場合に指定
@org.junit.Test public void specifyDefaultTimezone() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); SerializationConfig oldSerializationConfig = mapper.getSerializationConfig(); /** * 新的序列化配置,要配置时区 */ String timeZone = "GMT+8"; SerializationConfig newSerializationConfig = oldSerializationConfig.with(TimeZone.getTimeZone(timeZone)); mapper.setConfig(newSerializationConfig); TestVO vo = new TestVO(); vo.setTestDate(new Date()); String value = mapper.writeValueAsString(vo); System.out.println(value); }
注釈付きのフィールドで
@Data public class TestVoWithTimeZone { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date testDate; }
ここでは、追加のタイムゾーンは、手動でタイムゾーンの設定を指定します。
テストコード:
@org.junit.Test public void specifyTimezoneOnField() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); TestVoWithTimeZone vo = new TestVoWithTimeZone(); vo.setTestDate(new Date()); String value = mapper.writeValueAsString(vo); System.out.println(value); }
2以上の出力が正しいです。
分析する一切のソースコードはありません、単に時間のシーケンスを見て、コンフィギュレーションのシーケンスがあるでしょう。この構成では、2つの部分から構成:デフォルトの設定+クラスのカスタム設定。カスタム設定はデフォルトの設定を上書きします。
私たちの第二の方法は、デフォルトの設定を変更することであり、第三の方法は、カスタム設定がデフォルトの設定を上書き使用することです。
jackson
かなり重要な、特にspring cloud
家族のバケツ、feign
またこれで、restTemplate
また、同様に使用Spring MVC
してhttpmessageConverter
、その下に、この場所で学生の興味、表情。
あなたが興味を持ってJsonFormat処理されている場合は、次のような場所を見ることができます:
com.fasterxml.jackson.annotation.JsonFormat.Value#値(com.fasterxml.jackson.annotation.JsonFormat)(ここで休憩を行い、その後、ここでテストを実行します)
概要
私はほとんど問題RabbitMQのテンプレートを忘れ、そして最終的に私たちのソリューションは以下のとおりです。
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
ObjectMapper mapper = new ObjectMapper();
SerializationConfig oldSerializationConfig = mapper.getSerializationConfig();
/**
* 新的序列化配置,要配置时区
*/
String timeZone = environment.getProperty(CadModuleConstants.SPRING_JACKSON_TIME_ZONE);
SerializationConfig newSerializationConfig = oldSerializationConfig.with(TimeZone.getTimeZone(timeZone));
mapper.setConfig(newSerializationConfig);
Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter(mapper);
template.setMessageConverter(messageConverter);
template.setMandatory(true);
...设置callback啥的
return template;
}
その他の関連するソースコード:
https://gitee.com/ckl111/all-simple-demo-in-work/tree/master/jackson-demo