Search code examples
amazon-s3aws-sdkaws-java-sdk

S3 download pdf - REST API


I am trying to serve one of my PDF stored on S3 using Spring Boot Rest API.

Following is my code :

        byte[] targetArray = null;

        InputStream is = null;

        S3Object object = s3Client
                    .getObject(new GetObjectRequest("S3_BUCKET_NAME", "prefixUrl"));

        InputStream objectData = object.getObjectContent();

    BufferedReader reader = new BufferedReader(new InputStreamReader(objectData));

    char[] charArray = new char[8 * 1024];
    StringBuilder builder = new StringBuilder();
    int numCharsRead;
    while ((numCharsRead = reader.read(charArray, 0, charArray.length)) != -1) {

        builder.append(charArray, 0, numCharsRead);
    }
    reader.close();

    objectData.close();
    object.close();
    targetArray = builder.toString().getBytes();

    is = new ByteArrayInputStream(targetArray);


    return ResponseEntity.ok().contentLength(targetArray.length).contentType(MediaType.APPLICATION_PDF)
                    .cacheControl(CacheControl.noCache()).header("Content-Disposition", "attachment; filename=" + "testing.pdf")
                    .body(new InputStreamResource(is));

When I hit my API using postman, I am able to download PDF file but the problem is it is totally blank. What might be the issue ?

S3 streams the data and does not keep buffer and the data is in binary ( PDF ) so how to server such data to using Rest API.

How to solve this ?


Solution

  • Following simple code should work for you, not sure why are you trying to convert characters to bytes and vice-versa? Try this one, it works fine. Both PostMan/Browser.

    @GET
    @RequestMapping("/document")
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
    @Produces("application/pdf")
    public ResponseEntity<InputStreamResource> getDocument() throws IOException {
    
        final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
    
        S3Object object = s3.getObject("BUCKET-NAME", "DOCUMENT-URL");
        S3ObjectInputStream s3is = object.getObjectContent();
    
        return ResponseEntity.ok()
                    .contentType(org.springframework.http.MediaType.APPLICATION_PDF)
                    .cacheControl(CacheControl.noCache())
                    .header("Content-Disposition", "attachment; filename=" + "testing.pdf")
                    .body(new InputStreamResource(s3is));
    }