jms - MappingJackson2MessageConverter setTypeIdPropertyName with runtime class
jms - MappingJackson2MessageConverter setTypeIdPropertyName with runtime class
我正在尝试创建通用服务,该服务将使用 java 11、spring boot 2.2.6 和 MappingJackson2MessageConverter 处理向 MQ 发送消息。我想在我的其他服务中将它用作 bean。
但是当我发送消息时它有接口的类型而不是我正在发送的对象的 class。
我有接口 Entity
用于我要发送的所有对象和 class SomeEntity implements Entity
。所以消息有 "type" of (for array) [Lcom.company.Entity;而不是 [Lcom.company.SomeEntity;.
服务接口:
public interface MessageSender<T> {
void send(T[] entities);
}
默认实现:
public class DefaultMessageSender<T extends Entity> implements MessageSender<T> {
private final JmsTemplate jmsTemplate;
public DefaultMessageSender(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Override
public void send(T[] entities) {
jmsTemplate.convertAndSend(entities);
}
}
在其他spring引导服务中我将服务配置为bean:
@Bean
public MessageSender<SomeEntity> customerMessageSender(JmsTemplate jmsTemplate) {
return new DefaultMessageSender<>(jmsTemplate);
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("type");
return converter;
}
有没有办法强制转换器使用运行时 class 而不是接口的?
更新: 有 2 个问题:在 DefaultMessageSender 和数组中用 Entity class 替换所有 T 的类型擦除。 SomeEntity[] 不是 Entity[] 的子class,你不能转换它。
为了解决这个问题,我用列表替换了数组,并将方法抽象化,这样我就可以用具体的 classes 重新定义它。
@Bean
public MessageSender<SomeEntity> someEntityMessageSender(JmsTemplate jmsTemplate) {
return new AbstractDefaultMessageSender<>(jmsTemplate) {
@Override
protected void send(List<SomeEntity> items) {
var arr = items.toArray(new SomeEntity[0]);
jmsTemplate.convertAndSend(arr);
}
};
}
因为你发送的是数组
您可以设置从 Entity[]
到具体类型(如果只有一个)的映射,或者子类化并覆盖此方法以查看元素类型。
/**
* Set a type id for the given payload object on the given JMS Message.
* <p>The default implementation consults the configured type id mapping and
* sets the resulting value (either a mapped id or the raw Java class name)
* into the configured type id message property.
* @param object the payload object to set a type id for
* @param message the JMS Message on which to set the type id property
* @throws JMSException if thrown by JMS methods
* @see #getJavaTypeForMessage(javax.jms.Message)
* @see #setTypeIdPropertyName(String)
* @see #setTypeIdMappings(java.util.Map)
*/
protected void setTypeIdOnMessage(Object object, Message message) throws JMSException {
if (this.typeIdPropertyName != null) {
String typeId = this.classIdMappings.get(object.getClass());
if (typeId == null) {
typeId = object.getClass().getName();
}
message.setStringProperty(this.typeIdPropertyName, typeId);
}
}
我正在尝试创建通用服务,该服务将使用 java 11、spring boot 2.2.6 和 MappingJackson2MessageConverter 处理向 MQ 发送消息。我想在我的其他服务中将它用作 bean。
但是当我发送消息时它有接口的类型而不是我正在发送的对象的 class。
我有接口 Entity
用于我要发送的所有对象和 class SomeEntity implements Entity
。所以消息有 "type" of (for array) [Lcom.company.Entity;而不是 [Lcom.company.SomeEntity;.
服务接口:
public interface MessageSender<T> {
void send(T[] entities);
}
默认实现:
public class DefaultMessageSender<T extends Entity> implements MessageSender<T> {
private final JmsTemplate jmsTemplate;
public DefaultMessageSender(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
@Override
public void send(T[] entities) {
jmsTemplate.convertAndSend(entities);
}
}
在其他spring引导服务中我将服务配置为bean:
@Bean
public MessageSender<SomeEntity> customerMessageSender(JmsTemplate jmsTemplate) {
return new DefaultMessageSender<>(jmsTemplate);
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("type");
return converter;
}
有没有办法强制转换器使用运行时 class 而不是接口的?
更新: 有 2 个问题:在 DefaultMessageSender 和数组中用 Entity class 替换所有 T 的类型擦除。 SomeEntity[] 不是 Entity[] 的子class,你不能转换它。
为了解决这个问题,我用列表替换了数组,并将方法抽象化,这样我就可以用具体的 classes 重新定义它。
@Bean
public MessageSender<SomeEntity> someEntityMessageSender(JmsTemplate jmsTemplate) {
return new AbstractDefaultMessageSender<>(jmsTemplate) {
@Override
protected void send(List<SomeEntity> items) {
var arr = items.toArray(new SomeEntity[0]);
jmsTemplate.convertAndSend(arr);
}
};
}
因为你发送的是数组
您可以设置从 Entity[]
到具体类型(如果只有一个)的映射,或者子类化并覆盖此方法以查看元素类型。
/**
* Set a type id for the given payload object on the given JMS Message.
* <p>The default implementation consults the configured type id mapping and
* sets the resulting value (either a mapped id or the raw Java class name)
* into the configured type id message property.
* @param object the payload object to set a type id for
* @param message the JMS Message on which to set the type id property
* @throws JMSException if thrown by JMS methods
* @see #getJavaTypeForMessage(javax.jms.Message)
* @see #setTypeIdPropertyName(String)
* @see #setTypeIdMappings(java.util.Map)
*/
protected void setTypeIdOnMessage(Object object, Message message) throws JMSException {
if (this.typeIdPropertyName != null) {
String typeId = this.classIdMappings.get(object.getClass());
if (typeId == null) {
typeId = object.getClass().getName();
}
message.setStringProperty(this.typeIdPropertyName, typeId);
}
}