问题
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