title: Spring boot Angular2, return PDF in JSON
body: <p>I have a Spring boot REST API which must return a PDF. I have converted the PDF to a byte array, then I encoded it in base64 before returning it to the client.</p>
  
  <p>Here are my interface:</p>
  
  <pre><code>@ApiOperation(value = "Update an existing form", notes = "Update an existing form ", response = Void.class, tags={  })
      @ApiResponses(value = {
              @ApiResponse(code = 200, message = "form response", response = Void.class),
              @ApiResponse(code = 200, message = "unexpected error", response = Void.class) })
      @RequestMapping(value = "/forms/{formId}/submissions/{submissionId}/pdf",
              method = RequestMethod.GET)
      ResponseEntity&lt;Resource&gt; pdf(
              @ApiParam(value = "Id of the form that needs to be updated", required = true) @PathVariable("formId") Long formId,
              @ApiParam(value = "Id of the submission that needs to be updated", required = true) @PathVariable("submissionId") Long submissionId,
              @ApiParam(value = "token to be passed as a header", required = true) @RequestHeader(value = "token", required = true) String token
      );
  </code></pre>
  
  <p>And the implemented method:</p>
  
  <pre><code>@Override
      public ResponseEntity&lt;Resource&gt; pdf(@ApiParam(value = "Id of the form that needs to be updated", required = true) @PathVariable("formId") Long formId, @ApiParam(value = "Id of the submission that needs to be updated", required = true) @PathVariable("submissionId") Long submissionId, @ApiParam(value = "token to be passed as a header", required = true) @RequestHeader(value = "token", required = true) String token) {
          String name = JWTutils.getEmailInToken(token);
  
          if(name == null) {
              return new ResponseEntity&lt;&gt;(HttpStatus.FORBIDDEN);
          }
  
          User user = userRepository.findByEmail(name);
  
          if(user == null){
              return  new ResponseEntity&lt;&gt;(HttpStatus.FORBIDDEN);
          }
  
          Form form = formRepository.findById(formId);
  
          if(form == null){
              return new ResponseEntity&lt;&gt;(HttpStatus.NOT_FOUND);
          }
  
          Submission submission = submissionRepository.findOne(submissionId);
  
          if(submission == null){
              return new ResponseEntity&lt;&gt;(HttpStatus.NOT_FOUND);
          }
  
          //Saving the document
          final PDPage singlePage = new PDPage();
          final PDFont courierBoldFont = PDType1Font.COURIER_BOLD;
          final int fontSize = 12;
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          try (final PDDocument document = new PDDocument())
          {
              document.addPage(singlePage);
              final PDPageContentStream contentStream = new PDPageContentStream(document, singlePage);
              contentStream.beginText();
              contentStream.setFont(courierBoldFont, fontSize);
              contentStream.newLineAtOffset(150, 750);
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.showText("Hello PDFBox");
              contentStream.endText();
              contentStream.close();  // Stream must be closed before saving document.
              //document.save("pdfs/" + UUID.randomUUID().toString() + ".pdf");
              document.save(out);
          }
          catch (IOException ioEx)
          {
              ioEx.printStackTrace();
          }
  
          byte[] b64 = Base64.getEncoder().encode(out.toByteArray());
          ByteArrayResource resource = new ByteArrayResource(b64);
  
          return ResponseEntity.ok()
                  .contentLength(b64.length)
                  .contentType(MediaType.parseMediaType("application/octet-stream"))
                  .body(resource);
      }
  </code></pre>
  
  <p>And here is the code in Angular2:</p>
  
  <pre><code>generatePdf(){
      this.submissionService.generatePdf(this.form.id, this.submission.id).then(data =&gt; {
          console.log(JSON.stringify(data));
          let file = new Blob([atob(data._body)]);
          FileSaver.saveAs(file, 'helloworld.pdf')
      }).catch(error =&gt; {
          console.log(error);
      });
  }
  </code></pre>
  
  <p>The PDF i receive in the payload looks like this: <a href="https://pastebin.com/ep7XtqQs" rel="nofollow noreferrer">PasteBin</a></p>
  
  <p>When I open the downloaded PDF it contains only one page which is empty while the real pdf contains text. Any idea what's happening? I feel like it's about encoding.</p>
  
  <hr>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>I had to change my GET request in my service. I've added this to my request <code>responseType: ResponseContentType.Blob;</code></p>
  
  <pre><code>return this.http.get(this.formsUrl + "/" + formId + "/submissions/" + submissionId + "/pdf", {headers: headers, responseType: ResponseContentType.Blob})
          .toPromise()
          .then(res =&gt; res)
          .catch(this.handleError);
  </code></pre>