(spring boot or java) I have a problem opening URL PDF

Viewed 35

spring boot or java read/open pdf url and ResponseEntity attachment file .pdf

  1. Call the URL https://xxxxx.xxx/file.pdf
  2. Read the file from step 1 and display it. By setting the response value as follows:
Content-Type : application/pdf
Content-Transfer-Encoding : binary
Content-disposition : attachment; filename=filename.pdf
Content-Length : xxxx
URL url = new URL(apiReportDomain
                + "/rest_v2/reports/reports/cms/loan_emergency/v1_0/RTP0003_02.pdf?i_ref_code=" + documentId);
        System.out.println(url);
        String encoding = Base64.getEncoder().encodeToString(
                (apiReportUsername + ":" + apiReportPassword).getBytes(StandardCharsets.UTF_8));

        HttpURLConnection connectionApi = (HttpURLConnection) url.openConnection();
        connectionApi.setRequestMethod("GET");
        connectionApi.setDoOutput(true);
        connectionApi.setRequestProperty("Authorization", "Basic " + encoding);
        connectionApi.setRequestProperty("Content-Type", "application/pdf");
        InputStream content = connectionApi.getInputStream();
        BufferedReader in = new BufferedReader(
                new InputStreamReader(content));
                
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = in.read()) != -1) {
            sb.append((char) cp);
        }

        byte[] output = sb.toString().getBytes();

        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("charset", "utf-8");
        responseHeaders.setContentType(MediaType.valueOf("application/pdf"));
        responseHeaders.setContentLength(output.length);
        responseHeaders.set("Content-disposition", "attachment; filename=filename.pdf");

        return new ResponseEntity<byte[]>(output, responseHeaders, HttpStatus.OK);

enter image description here

which the result i got is a blank page But in fact, this PDF contains a full sheet of text.

2 Answers

Update this if it does or does not operate, I think the problem would be the https and certificate verification at client download by your original connection. You need the certificate to decrypt the pdf and formally accept the certificate. See JCA cryptography API.

Also the following is best MIME type for sending binary download. Content-Type : application/octet-stream

https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/HttpsURLConnection.html

The issue is that the server needs to fetch the file from the internet, and then pass it on. Except of a redirect (which would look like cross-site traffic).

First write local code to fetch the PDF in a local test application. It could be that you need to use java SE HttpClient.

It just might be you need to fake a browser as agent, and accept cookies, follow a redirect. That all can be tested by a browser's development page looking at the network traffic in detail.

Then test that you can store a file with the PDF response.

And finally wire the code in the spring application, which is very similar on yielding the response. You could start with a dummy response, just writing some hard-coded bytes.


After info in the question

You go wrong in two points:

  • PDFs are binary data, String is Unicode, with per char 2 bytes, requiring a conversion back and forth: the data will be corrupted and the memory usage twice, and it will be slow.

  • String.getBytes(Charset) and new String(byte[], Charset) prevent that the default Charset of the executing PC is used.

  • Keeping the PDF first entirely in memory is not needed. But then you are missing the Content-Length header.

      InputStream content = connectionApi.getInputStream();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      content.transferTo(baos);
      byte[] output = baos.toByteArray();
    
      HttpHeaders responseHeaders = new HttpHeaders();
      responseHeaders.set("charset", "utf-8");
      responseHeaders.setContentType(MediaType.valueOf("application/pdf"));
      responseHeaders.setContentLength(output.length);
      responseHeaders.set("Content-disposition",
          "attachment; filename=filename.pdf");
    
Related