如何将消息直接绑定到我的对象类

问题描述:

我得到如下所示的消息,其中包含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类

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中不能转换到 com.bosch.bip.dto.ExchangeDTO

+0

您是否试图错误地将{inputMap = {},outputMap = {activityId = 10001002,activityStatus = SUCCESS}}解析为JSON,错误似乎指向了这一点。 – Ironluca

“在java代码中”是什么意思?对象映射器期待JSON字符串。

{"ORCH_KEY":{"inputMap":{},"outputMap":{"activityId":"10001002","activityStatus":"SUCCESS"}}} 

如果您使用的是Spring AMQP的Json变频器,JSON将已经被转换成一个Map地图。

{inputMap={}, outputMap={activityId=10001002, activityStatus=SUCCESS}} 

看起来像是一个toString()调用结果。

您需要自定义Jackson2JsonMessageConverter自定义ClassMapper告诉转换器你想要一个ExchangeDTO创建。

您可以使用DefaultClassMapper;如果消息中没有信息来确定类型,默认类映射器将回退到默认类型: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"}}}' 

and

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。如果您使用与我相同的配置,我不会看到这是可能的。

如果您可以在展示问题的地方发布一个小型测试项目,我可以看看有什么不对。

+0

你好加里,我现在面临异常。 ** java.util.LinkedHashMap不能转换为com.bosch.bip.dto.ExchangeDTO ** – Chandan

+0

您使用的是什么版本的Spring AMQP?看到我的编辑,你的用例对我来说工作得很好。 –

+0

我正在使用1.6.1。我能够看到类似于你的输出。但问题是'ExchangeDTO exchangeDTO = next.getValue();' – Chandan