весенняя загрузка как загрузить все файлы из папки s3 в локальный каталог? - PullRequest
2 голосов
/ 18 июня 2020

Я новичок в Spring, я хочу использовать TransferManager для загрузки всех файлов в определенной папке, и я также хочу знать, как мне заставить пользователей получить свой локальный путь при загрузке файлов на веб-странице. После запуска кода код не сообщает об ошибке, но в локальном пути, который я написал, также нет файла s3, ниже мой код:

  @RequestMapping(method = RequestMethod.GET, path = "/{id}/download")
    void downloadGroup(
        @PathVariable("id") @NotNull Integer id
    ) throws IOException {
        String bucketName;
        String keyPrefix;
        String destinationDirectory = "Users/Download";
        AWSCredentials credentials = new BasicAWSCredentials(
            awsAccessKeyId, awsSecretAcessKey);

        AmazonS3 s3 = AmazonS3ClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(credentials))
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    awsServiceEndpoint,
                    awsDefaultRegion))
            .build();

        ObjectListing objects = s3.listObjects(bucketName, keyPrefix);

        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, project);

        TransferManager tm = TransferManagerBuilder.standard()
            .withS3Client(s3)
            .build();

//        Download download = tm.download(bucketName, keyPrefix, new File(destinationDirectory));
        try {
            MultipleFileDownload download = tm.downloadDirectory(
                bucketName,
                keyPrefix,
                new File(destinationDirectory));
            download.waitForCompletion();
            LOG.info("Download complete.");
        } catch (AmazonClientException amazonClientException) {
            LOG.info("Unable to download file, download was aborted.");
            throw new RuntimeException(amazonClientException);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        tm.shutdownNow();
    }

Ниже мой недавно измененный код:

@RequestMapping(method = RequestMethod.GET, path = "/{id}/download")
public ResponseEntity<ByteArrayResource> downloadGroup(
        @PathVariable("id") @NotNull Integer id
    ) throws IOException {
        String bucketName;
        String keyPrefix;

        AWSCredentials credentials = new BasicAWSCredentials(
            awsAccessKeyId, awsSecretAcessKey);

        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(credentials))
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    awsServiceEndpoint,
                    awsDefaultRegion))
            .build();
        byte[] data = null;
        String fileName = null;
        ObjectListing objects = s3Client.listObjects(bucketName, keyPrefix);
        List<S3ObjectSummary> objectSummaries = objects.getObjectSummaries();
        for (S3ObjectSummary objectSummary : objectSummaries) {
            if (objectSummary.getKey().contains(".csv")) {
                data = downloadFile(s3Client, bucketName, objectSummary.getKey());
                fileName = URLEncoder.encode(objectSummary.getKey(), "UTF-8").replaceAll("\\+", "%20");
                System.out.println(fileName);
            }
        }
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        httpHeaders.setContentLength(data.length);
        httpHeaders.setContentDispositionFormData("attachment", fileName);
        ByteArrayResource resource = new ByteArrayResource(data);
        return new ResponseEntity<>(resource, httpHeaders, HttpStatus.OK);
    }
public byte[] downloadFile(AmazonS3 s3, String bucketName, String keyName) {
        byte[] content = null;
        S3Object s3Object = s3.getObject(bucketName, keyName);
        S3ObjectInputStream stream = s3Object.getObjectContent();
        try {
            content = IOUtils.toByteArray(stream);
            s3Object.close();
        } catch(final IOException ex) {
            LOG.info("IO Error Message= " + ex.getMessage());
        }
        return content;
    }

1 Ответ

1 голос
/ 18 июня 2020

При чтении примера происхождения из https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-s3-transfermanager.html#tranfermanager -download-directory и чтении вашего кода и желаемого поведения выше, я думаю, ваша проблема в том, что вы сохраняете содержимое s3 на стороне приложения весенней загрузки .

Например: когда вы запустили приложение весенней загрузки на

/opt/myserver/MyServer.jar

, использование вашего кода загрузит данные содержимого вашей корзины s3 в /opt/myserver/Users/Download

Но ваше желаемое поведение - предоставить файлы пользователям на стороне браузера - или я это пропустил?

Я бы попытался получить данные содержимого s3 из вашего весеннего загрузочного приложения и вернуть Zip OutputStream в ожидающая сторона клиента (браузер) (возможно, вам придется загрузить временные файлы, заархивировать их, удалить временное содержимое и т. д. c.)

...