简体   繁体   English

从 AWS lambda 下载文件

[英]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.在上面的代码中,我有requestHandler从 AWS S3 中提取文件,它应该将它作为响应发送。 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.但由于某种原因,我无法下载它,因为当我保存了这个文件时,它无法打开,出现file damaged etc.错误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.我在有关它的 AWS 文档中找不到任何 Java 示例。 Most of the are about Python or JavaScript.大多数是关于 Python 或 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.对我来说,这意味着我必须将文件包装到 JSON 对象中,然后从我的处理程序方法中返回它。 But that does not work for me cause, I am getting what you can see 2 snippet code above.但这对我不起作用,因为我得到了你可以在上面看到的 2 个片段代码。 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.如果@jarmod 可以理解我想从 Lambda 下载,并且他可以为我指出创建文件重定向请求的良好方向,因为将对象从 S3 拉到 Lambda 然后再次通过 HTTP 发送它是错误的方法,我认为 post够清楚了。

That why I decide to post my solution, which thanks to @jarmod I could come up with.这就是为什么我决定发布我的解决方案,这要归功于 @jarmod 我可以想出。 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.在这个处理程序中,我使用S3Presinger ,如果有人使用 AWS 网关创建 API 并希望下载存储在 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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