Search code examples
javajsonjacksonapache-camelmarshalling

Apache camel cannot marshal to JSON from InputStreamCache


In Apache Camel I expose a REST service, take its input to call a SOAP service and then I'd like to marshal the SOAP response to JSON. My RouteBuilder looks roughly like this:

rest("/api")
 .get("/client/{id}")
 .to("direct:getClient");

from("direct:getClient")
 .log(LoggingLevel.INFO, "Getting client with id ${id}")
 .process(new GetClientProcessor())
 .marshal().jaxb()
 .to("spring-ws:http://localhost:9000/searchClient?soapAction=search")
 .process(new ClientProcessor())
 .marshal().json(JsonLibrary.Jackson);

I get the following error while marshalling the result to JSON:

com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.camel.converter.stream.InputStreamCache and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:275)
    at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1110)
    at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1135)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
    ...

I know why this is happening, as I have turned on stream caching by default. However, I don't know how to fix this without turning off stream caching.

I have searched through the Camel documentation, mailing lists and fora, but I haven't found useful information sofar.


Solution

  • I finally solved it. The problem had nothing to do with described routes, rather the global rest configuration:

    RestConfiguration restConfiguration = new RestConfiguration();
    restConfiguration.setComponent("servlet");
    restConfiguration.setBindingMode(RestConfiguration.RestBindingMode.json);
    restConfiguration.setHost("localhost");
    restConfiguration.setPort(serverPort);
    
    camelContext.setRestConfiguration(restConfiguration);
    

    The third line, setting the binding mode, is unnecessary as I state explicitly when I'd like to map to JSON and also which framework I use. After I remove this line everything works like a charm.

    At this moment I don't exactly know how or why this has solved my problem, but I'm happy it did ;)