Search code examples
javaspring-bootthymeleafmicroservicesitext7

iText 7 - How to send to an API and receive/render on the other end


I am trying to send a PDF that will be created in memory from one API to another API which will then render it in an HTML page. Info about my technologies:

  • Springboot
  • Microservices Architecture (with Eureka)
  • Java
  • Thymeleaf

What I have so far is a microservice which receives a String input from an input field (through an API) and then I get it here and I believe I prepare a pdf in memory(haven't tested it yet):

    public InputStream convert(String input) throws FileNotFoundException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    PdfWriter writer = new PdfWriter(out);
    PdfDocument pdf = new PdfDocument(writer);
    Document document = new Document(pdf);
    document.add(new Paragraph(input));
    document.close();

    return new ByteArrayInputStream(out.toByteArray());
}

Here is my sending controller currently:

    @RequestMapping("/cnv")
public InputStream doConversion(@RequestParam(defaultValue = "0") String input) {
    try {
        return textToPDFService.c2f(input);
    } catch (FileNotFoundException e) {
        throw new RuntimeException("Exception thrown while writing file: " + e);
    }

}

I don't have any code to show for the web server that receives it yet, but you can expect since this is Springboot I am going to have a relevant endpoint in a @Controller and a method that communicates with my microservice of type @Service.

Question is, how do I receive this in InputStream in my web server's service and render it? Helpful resources are also welcome.

PS: I have never used iText before, Springboot or microservices prior to this. Also, never had a requirement about PDFs (yeah, I know I am a big noob).


Solution

  • It seems I got my answer. Make sure you return in your controller that performs the conversions a byte[] or even better ResponseEntity<byte[]>. Then, you should add headers to your request like so:

     return ResponseEntity.ok()
                    .header(headerKey, headerValue)
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(res);
    

    On your receiving microservice you need a service which will do the following:

    // Setup Headers & URL
    String url = blah blah..;
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_PDF));
    HttpEntity<String> entity = new HttpEntity<>("body", headers);
    // Get Result from Microservice
    return restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class, input);
    

    Of course, this will return to you this ResponseEntity<byte[]>. You can just pass this to the controller endpoint and you are done:

    return textToPDFService.textToPDFRequest(input);
    

    Keep in mind you should mind exceptions and HTTP codes, but this will do as a minimal solution.