简体   繁体   中英

Download file from AWS lambda

class DownloadFileHandler RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

  @Overrider
  public APIGatewayProxyResponseEvent handlerRequest(APIGatewayProxyRequestEvent event, Context context) {
      String fileName = event.getQueryStringParameters().get("fileName");
      AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

      AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(Regions.US_EAST_2).build();
      GetObjectRequest request = new GetObjectRequest(bucket, fileName);
      S3Object objectFile = s3Client.getObject(request);
      S3ObjectInputStream objectInputStream = objectFile.getObjectContent();
      // latest I was trying this
      byte [] fileBytes = new byte[0];

      try {
        fileBytes = objectInputStream.readAllBytes();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    Map<String, String> headers = new LinkedHashMap<>();
    headers.put("Content-Type", "application/json");
    headers.put("Accept", "application/octet-stream");
    headers.put("Content-Disposition", String.format(Locale.UK, "attachment; filename=%s", fileName));
    headers.put("Content-Length", String.valueOf(fileBytes.length));
    // I tried this 
    JSONObject response = new JSONObject();
    response.append("file", objectFile);

    APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent()
      .withHeaders(headers)
      .withStatusCode(200)
      .withIsBase64Encoded(true)
      .withBody(Base64.getEncoder().encodeToString(fileBytes));

    return responseEvent;
  }
}

In the code above I have requestHandler which pulling file from AWS S3 and it should send it over as response. I code above you can see that I was trying at least two approaches non of the work. I mean I am able to send file as string, but I can not download this file. What I am getting instead of file content is

DIxMTc1NSAwMDAwMCBuDQowMDAwMjExODg3IDAwMDAwIG4NCjAwMDAyMTE5MTQgMDAwMDAgbg0KMDAwMDIxMjM5MiAwMDAwMCBuDQowMDAwMjE3NDQ3IDAwMDAwIG4NCjAwMDAyMTc1MTcgMDAwMDAgbg0KMDAwMDIxNzc4MiAwMDAwMCBuDQowMDAwMjE3ODYzIDAwMDAwIG4NCjAwMDAyMzExMDAgMDAwMDAgbg0KMDAwMDIzMTEyNyAwMDAwMCBuDQowMDAwMjMxNTA5IDAwMDAwIG4NCjAwMDAyMzY2MDkgMDAwMDAgbg0KMDAwMDIzNjY3OSAwMDAwMCBuDQowMDAwMjM2OTUwIDAwMDAwIG4NCjAwMDAyMzcwMzEgMDAwMDAgbg0KMDAwMDI0NTA4NSAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDE2Ny9Sb290IDE4IDAgUi9JbmZvIDE2IDAgUi9JRFs8RTdCRDQzNDY0Mzg0Q0M0OTU1QTVBQTNBRTIzMzQxNUI+PDM5RDcyRDQ5OEJGMzFFNDhCMEQ5QjkxODBFOEIzQzVFPl0vUHJldiAyMDI0MzA+Pg0Kc3RhcnR4cmVmDQoyNDk0NDgNCiUlRU9GDQo=%
[content cut out]

So I assume that is the file. But for some reason I am not able to download it, cause when I have this file saved it can not be opened, I am getting error like file damaged etc.

I would appreciate any help with understanding why this approach is not working? I could not find any example for Java in AWS documentation about it. Most of the are about Python or JavaScript. And it seems like I do not understand them cause I see code like

response = {
  "statusCode" : 200,
  "body" : file
}

or something similar. And for me it means that I have to wrap the file into JSON object and just return it from my handler method. But that does not work for me cause, I am getting what you can see 2 snippet code above. Please explain what I am doing wrong and what I am not understanding?

I am not sure why this post get minus points, but whatever. If @jarmod could understand that I want download from Lambda, and he could point me in good direction of creating redirected requests for the files, because pulling object from S3 to Lambda and then sending it via HTTP again, is wrong approach, I think post is clear enough.

That why I decide to post my solution, which thanks to @jarmod I could come up with. In this handler I am using S3Presinger which I think is very useful if some one create the API with AWS Gateways which use AWS Lambda and want to download files stored on AWS S3.

 public class DownloadFileHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        String bucket = "";

        try (InputStream input = new FileInputStream("./config/application.properties")) {
            Properties properties = new Properties();
            properties.load(input);

            bucket = properties.getProperty("bucket");
        } catch (IOException e) {
            e.printStackTrace();
        }

        String fileName = event.getQueryStringParameters().get("fileName");

        S3Presigner presigner = S3Presigner.builder().build();

        GetObjectPresignRequest presignRequest = GetObjectPresignRequest
                .builder()
                .signatureDuration(Duration.ofMinutes(10))
                .getObjectRequest(GetObjectRequest.builder().bucket(bucket).key(fileName).build())
                .build();

        PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(presignRequest);

        String presignedURL = presignedGetObjectRequest.url().toString();
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("Location", presignedURL);

        APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent()
                .withHeaders(headers)
                .withStatusCode(302);

        return responseEvent;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM