1

I have a service that receives a file and send it to a Camel route. On that route, I’d like to unmarshal that file using BeanIO, but it doesn’t recognize inputs of type InputStream.

@RestController
@RequestMapping(value = "/file")
public class FileController {

    @Autowired
    private CamelContext camelContext;

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public void upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        ProducerTemplate template = camelContext.createProducerTemplate();
        template.sendBody("direct:routeTest", new ByteArrayInputStream(multipartFile.getBytes()));
    }

}

@Component
public class SampleRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("direct:routeTest")
                .log("${body}")
                .to("dataformat:beanio:unmarshal?mapping=mapping.xml&streamName=testFile")
                .process(msg -> msg.getIn()
                        .getBody(List.class)
                        .forEach(o -> {...}))
                .end();
    }

}

I have tested a route that reads the file using the File component, and sends the result to the BeanIO component. In that case it works.

How can I use BeanIO with inputs of type InputStream on Apache Camel? Is there any component that can transform my InputStream into something compatible with the BeanIO component?

Marcos Tanaka
  • 3,112
  • 3
  • 25
  • 41
  • Did you get any exception? Did you get any output message on `log("${body}")`? – mgyongyosi Aug 22 '17 at 10:41
  • No exceptions. `.log("${body}")` gives me the content of the file. It turns out that the problem was exactly that line. I thought that `.log("${body}")` would return the body's content to the next route, but it doesn't return anything. When I removed this line, it worked. – Marcos Tanaka Aug 22 '17 at 11:58
  • 1
    Yep, when you called `.log("${body}")` on the InputStream it read the stream and after that the position was at the end of the stream. – mgyongyosi Aug 22 '17 at 12:07

2 Answers2

3

As mgyongyosi said, when .log("${body}") reads the stream, the position go to the end of it. To solve this we can reset the position of the InputStream after reading it:

from("direct:routeTest")
        .log("${body}")
        .process(exchange -> ((InputStream) exchange.getIn().getBody()).reset())
        .to("dataformat:beanio:unmarshal?mapping=mapping.xml&streamName=testFile")

or remove the line .log("${body}").

Marcos Tanaka
  • 3,112
  • 3
  • 25
  • 41
1

Other solution can be to add .streamCaching() to the route. Then you can read the same stream multiple times. Official documentation

mgyongyosi
  • 2,557
  • 2
  • 13
  • 20