如何将消息直接绑定到我的对象 class
How to bind a message directly to my object class
我收到如下消息,其中包含 2 个 HashMap(inputMap 和 outputMap)。这是使用 ObjectMapper 的正确方法吗?
示例消息:
在 RabbitMQ 中:
{"ORCH_KEY":{"inputMap":{},"outputMap":{"activityId":"10001002","activityStatus":"SUCCESS"}}}
在配置代码中
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
Jackson2JsonMessageConverter messageConverter=new Jackson2JsonMessageConverter();
DefaultClassMapper classMapper = new DefaultClassMapper();
classMapper.setDefaultType(ExchangeDTO.class);
messageConverter.setClassMapper(classMapper);
factory.setMessageConverter(messageConverter);
消费者代码
@RabbitListener(containerFactory = "adapterOPListenerContainerFactory", queues = Constants.ADAPTOR_OP_QUEUE)
public void handleAdapterQueueMessage(HashMap<String, ExchangeDTO> adapterOutputMap) {
logger.info("Adapter Handler::::::::::"+this.getClass().getCanonicalName());
try {
logger.info("Adapter Output Map:::::::::::" + adapterOutputMap);
if(adapterOutputMap.size()==1){
Iterator<Entry<String, ExchangeDTO>> iterator = adapterOutputMap.entrySet().iterator();
Entry<String, ExchangeDTO> next = iterator.next();
String ORCH_KEY =next.getKey();
logger.info("Ochestration Key:::::::::::" + ORCH_KEY);
ExchangeDTO exchangeDTO = next.getValue();
logger.info("Size of OutputMap:::::"+exchangeDTO.getOutputMap().size());
ExchangeDTO class
public class ExchangeDTO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private HashMap<String, Object> inputMap = new HashMap<String, Object>();
private HashMap<String, Object> outputMap = new HashMap<String, Object>();
public HashMap<String, Object> getInputMap() {
return inputMap;
}
public void setInputMap(HashMap<String, Object> inputMap) {
this.inputMap = inputMap;
}
public HashMap<String, Object> getOutputMap() {
return outputMap;
}
public void setOutputMap(HashMap<String, Object> outputMap) {
this.outputMap = outputMap;
}
}
我遇到如下错误:
java.util.LinkedHashMap cannot be cast to
com.bosch.bip.dto.ExchangeDTO
"in java code" 是什么意思?对象映射器需要一个 JSON 字符串。
{"ORCH_KEY":{"inputMap":{},"outputMap":{"activityId":"10001002","activityStatus":"SUCCESS"}}}
如果您正在使用 Spring AMQP Json 转换器,JSON 将已经转换为地图中的地图。
{inputMap={}, outputMap={activityId=10001002, activityStatus=SUCCESS}}
看起来像是对结果的 toString()
调用。
您需要使用自定义 ClassMapper
来自定义 Jackson2JsonMessageConverter
,告诉转换器您想要创建 ExchangeDTO
。
你可以使用一个DefaultClassMapper
;如果消息中没有确定类型的信息,则默认 class 映射器回退到其默认类型:myDefaultClassMapper.setDefaultType(MyType.class);
。然后将映射器注入消息转换器。
编辑
我只是 运行 一个测试,它对我来说工作得很好(注意不需要自定义 classmapper)...
public static class DTO {
private Map<String, Object> inputMap;
private Map<String, Object> outputMap;
public Map<String, Object> getInputMap() {
return this.inputMap;
}
public void setInputMap(Map<String, Object> inputMap) {
this.inputMap = inputMap;
}
public Map<String, Object> getOutputMap() {
return this.outputMap;
}
public void setOutputMap(Map<String, Object> outputMap) {
this.outputMap = outputMap;
}
@Override
public String toString() {
return "DTO [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
}
}
@RabbitListener(queues = QUEUE, containerFactory = "adapterOPListenerContainerFactory")
public void listen(HashMap<String, DTO> message) {
System.out.println("Result:" + message.getClass() + ":" + message);
latch.countDown();
}
@Bean
public SimpleRabbitListenerContainerFactory adapterOPListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
return factory;
}
和
... Received message: (Body:'{"MAP":{"inputMap":{"foo":"bar"},"outputMap":{"baz":"qux"}}}'
和
Result:class java.util.HashMap:{MAP=DTO [inputMap={foo=bar}, outputMap={baz=qux}]}
此机制(将参数类型传送给 JSON 转换器)需要 Spring AMQP 1.6 或更高版本 - 1.6.2 是当前版本。
EDIT2
对我来说很好用...
@RabbitListener(queues = QUEUE, containerFactory = "adapterOPListenerContainerFactory")
public void listen(HashMap<String, DTO> dtos) {
System.out.println("Result:" + dtos.getClass() + ":" + dtos);
DTO dto = dtos.entrySet().iterator().next().getValue();
System.out.println(dto);
latch.countDown();
}
和
Result:class java.util.HashMap:{MAP=DTO [inputMap={foo=bar}, outputMap={baz=qux}]}
DTO [inputMap={foo=bar}, outputMap={baz=qux}]
您的地图值似乎没有被转换为 DTO,而是默认值 LinkedHashMap
。如果您使用与我相同的配置,我不明白这怎么可能。
如果你可以 post 在某处展示问题的小型测试项目,我可以看看有什么问题。
我收到如下消息,其中包含 2 个 HashMap(inputMap 和 outputMap)。这是使用 ObjectMapper 的正确方法吗?
示例消息:
在 RabbitMQ 中:
{"ORCH_KEY":{"inputMap":{},"outputMap":{"activityId":"10001002","activityStatus":"SUCCESS"}}}
在配置代码中
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
Jackson2JsonMessageConverter messageConverter=new Jackson2JsonMessageConverter();
DefaultClassMapper classMapper = new DefaultClassMapper();
classMapper.setDefaultType(ExchangeDTO.class);
messageConverter.setClassMapper(classMapper);
factory.setMessageConverter(messageConverter);
消费者代码
@RabbitListener(containerFactory = "adapterOPListenerContainerFactory", queues = Constants.ADAPTOR_OP_QUEUE)
public void handleAdapterQueueMessage(HashMap<String, ExchangeDTO> adapterOutputMap) {
logger.info("Adapter Handler::::::::::"+this.getClass().getCanonicalName());
try {
logger.info("Adapter Output Map:::::::::::" + adapterOutputMap);
if(adapterOutputMap.size()==1){
Iterator<Entry<String, ExchangeDTO>> iterator = adapterOutputMap.entrySet().iterator();
Entry<String, ExchangeDTO> next = iterator.next();
String ORCH_KEY =next.getKey();
logger.info("Ochestration Key:::::::::::" + ORCH_KEY);
ExchangeDTO exchangeDTO = next.getValue();
logger.info("Size of OutputMap:::::"+exchangeDTO.getOutputMap().size());
ExchangeDTO class
public class ExchangeDTO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private HashMap<String, Object> inputMap = new HashMap<String, Object>();
private HashMap<String, Object> outputMap = new HashMap<String, Object>();
public HashMap<String, Object> getInputMap() {
return inputMap;
}
public void setInputMap(HashMap<String, Object> inputMap) {
this.inputMap = inputMap;
}
public HashMap<String, Object> getOutputMap() {
return outputMap;
}
public void setOutputMap(HashMap<String, Object> outputMap) {
this.outputMap = outputMap;
}
}
我遇到如下错误:
java.util.LinkedHashMap cannot be cast to com.bosch.bip.dto.ExchangeDTO
"in java code" 是什么意思?对象映射器需要一个 JSON 字符串。
{"ORCH_KEY":{"inputMap":{},"outputMap":{"activityId":"10001002","activityStatus":"SUCCESS"}}}
如果您正在使用 Spring AMQP Json 转换器,JSON 将已经转换为地图中的地图。
{inputMap={}, outputMap={activityId=10001002, activityStatus=SUCCESS}}
看起来像是对结果的 toString()
调用。
您需要使用自定义 ClassMapper
来自定义 Jackson2JsonMessageConverter
,告诉转换器您想要创建 ExchangeDTO
。
你可以使用一个DefaultClassMapper
;如果消息中没有确定类型的信息,则默认 class 映射器回退到其默认类型:myDefaultClassMapper.setDefaultType(MyType.class);
。然后将映射器注入消息转换器。
编辑
我只是 运行 一个测试,它对我来说工作得很好(注意不需要自定义 classmapper)...
public static class DTO {
private Map<String, Object> inputMap;
private Map<String, Object> outputMap;
public Map<String, Object> getInputMap() {
return this.inputMap;
}
public void setInputMap(Map<String, Object> inputMap) {
this.inputMap = inputMap;
}
public Map<String, Object> getOutputMap() {
return this.outputMap;
}
public void setOutputMap(Map<String, Object> outputMap) {
this.outputMap = outputMap;
}
@Override
public String toString() {
return "DTO [inputMap=" + this.inputMap + ", outputMap=" + this.outputMap + "]";
}
}
@RabbitListener(queues = QUEUE, containerFactory = "adapterOPListenerContainerFactory")
public void listen(HashMap<String, DTO> message) {
System.out.println("Result:" + message.getClass() + ":" + message);
latch.countDown();
}
@Bean
public SimpleRabbitListenerContainerFactory adapterOPListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
return factory;
}
和
... Received message: (Body:'{"MAP":{"inputMap":{"foo":"bar"},"outputMap":{"baz":"qux"}}}'
和
Result:class java.util.HashMap:{MAP=DTO [inputMap={foo=bar}, outputMap={baz=qux}]}
此机制(将参数类型传送给 JSON 转换器)需要 Spring AMQP 1.6 或更高版本 - 1.6.2 是当前版本。
EDIT2
对我来说很好用...
@RabbitListener(queues = QUEUE, containerFactory = "adapterOPListenerContainerFactory")
public void listen(HashMap<String, DTO> dtos) {
System.out.println("Result:" + dtos.getClass() + ":" + dtos);
DTO dto = dtos.entrySet().iterator().next().getValue();
System.out.println(dto);
latch.countDown();
}
和
Result:class java.util.HashMap:{MAP=DTO [inputMap={foo=bar}, outputMap={baz=qux}]}
DTO [inputMap={foo=bar}, outputMap={baz=qux}]
您的地图值似乎没有被转换为 DTO,而是默认值 LinkedHashMap
。如果您使用与我相同的配置,我不明白这怎么可能。
如果你可以 post 在某处展示问题的小型测试项目,我可以看看有什么问题。