Apache Camel: ProducerTemplate not unmarshalling the response

流过昼夜 提交于 2020-01-05 03:33:30

问题


Camel version: 2.15.6

I used the ProducerTemplate to send a http request and get the response like this.

from("direct:getContact")
.process(new Processor() {
                    @Override
                    public void process(Exchange exchange) throws Exception {
                        CamelContext context = exchange.getContext();
                        ProducerTemplate producerTemplate = context.createProducerTemplate();
Contact contact = producerTemplate.requestBodyAndHeaders( 
                                "http://localhost:8080/api/contact/2345", 
                                null, headers, Contact.class); 

logger.info("Contact is: " + new ObjectMapper().writeValueAsString(contact)); 

exchange.getOut().setBody(contact);

});

I get the contact as null.

When I try to get it as Object like this:

Object contact = producerTemplate.requestBodyAndHeaders( 
                                "http://localhost:8080/api/contact/2345", 
                                null, headers); 


logger.info("Contact is: " + new ObjectMapper().writeValueAsString(contact)); 

com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEA

NS) )

Why is ProducerTemplate not able to unmarshall the response to the specified object? How can this be achieved?

Edit

The Fix I observed is as follows: If I first get the output as string and then deserialize it, it works.

String responseString = producerTemplate.requestBodyAndHeaders( 
                                    "http://localhost:8080/api/contact/2345", 
                                    null, headers, String.class); 

Contact contact = new ObjectMapper().readValue(responseString, Contact.class);

回答1:


My Answer is more of an combination of Rafal's to show how you can tie his code back into your solution to get the desired result. Thanks Rafal for setting up the sub route in this sample.

Assumptions: You have the rest API up and available already

Your new Code:

from("direct:getContact")
    .process(new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            CamelContext context = exchange.getContext();
            ProducerTemplate producerTemplate = context.createProducerTemplate();
            //Call another route not the rest endpoint
            Future<Contact> contact = producerTemplate.requestBodyAndHeaders( 
                "direct:RetrieveContactRoute", 
                 null, headers, Contact.class); 

             logger.info("Contact is: " + new ObjectMapper().writeValueAsString(contact.get())); 

             //Set the In Body not the Out Body 
             exchange.getIn().setBody(contact.get());
    }); 

A separate Route

JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
jacksonDataFormat.setUnmarshalType(Contact.class);

from("direct:RetrieveContactRoute")
    .to("http://localhost:8080/api/contact/2345")
    .unmarshal(jacksonDataFormat);



回答2:


Try to create Your route like this:

//org.apache.camel.component.jackson.JacksonDataFormat

JacksonDataFormat jacksonDataFormat = new JacksonDataFormat();
jacksonDataFormat.setUnmarshalType(Contact.class);

from("direct:getContact")
    .to("http://localhost:8080/api/contact/2345")
    .unmarshal(jacksonDataFormat);

After unmarshalling You should have Contant object in body.

Dependency is from:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jackson</artifactId>
    <version>2.15.6</version>
</dependency>


来源:https://stackoverflow.com/questions/37409460/apache-camel-producertemplate-not-unmarshalling-the-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!