spring批处理文件编写器直接写入亚马逊s3存储,无需PutObjectRequest

use*_*722 5 java amazon-s3 amazon-web-services spring-batch

我正在尝试将文件上传到亚马逊 s3。我不想上传,而是想使用 Spring Batch 从数据库读取数据并将文件直接写入 s3 存储。无论如何,我们能做到吗?

Mah*_*ine 3

Spring Cloud AWS 添加了对 Amazon S3 服务的支持,以通过资源加载器和 s3 协议加载和写入资源。配置完 AWS 资源加载器后,您可以编写自定义 Spring Batch 编写器,如下所示:

import java.io.OutputStream;
import java.util.List;

import org.springframework.batch.item.ItemWriter;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.WritableResource;

public class AwsS3ItemWriter implements ItemWriter<String> {

    private ResourceLoader resourceLoader;

    private WritableResource resource;

    public AwsS3ItemWriter(ResourceLoader resourceLoader, String resource) {
        this.resourceLoader = resourceLoader;
        this.resource = (WritableResource) this.resourceLoader.getResource(resource);
    }

    @Override
    public void write(List<? extends String> items) throws Exception {
        try (OutputStream outputStream = resource.getOutputStream()) {
            for (String item : items) {
                outputStream.write(item.getBytes());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那么您应该能够将此编写器与 S3 资源(例如s3://myBucket/myFile.log.

无论如何,我们能做到吗?

请注意,我没有编译/测试之前的代码。我只是想给你一个如何做的起点。

编辑:前面的代码片段可能会为每个块写入一个文件,这是不正确的。这是一个更新版本,其中输出流仅初始化一次。

import java.io.IOException;
import java.io.OutputStream;

import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamWriter;
import org.springframework.core.io.WritableResource;

public class AwsS3ItemWriter implements ItemStreamWriter<String> {

    private final WritableResource resource;

    private OutputStream outputStream;

    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        try {
            this.outputStream = resource.getOutputStream();
        } catch (IOException e) {
            throw new ItemStreamException("Unable to get output stream", e);
        }
    }

    public AwsS3ItemWriter(WritableResource resource) {
        this.resource = resource;
    }

    @Override
    public void write(Chunk<? extends String> items) throws Exception {
        for (String item : items) {
            outputStream.write(item.getBytes());
        }
    }

    @Override
    public void close() throws ItemStreamException {
        try {
            outputStream.close();
        } catch (IOException e) {
            throw new ItemStreamException("Unable to close output stream", e);
        }
    }
    
}
Run Code Online (Sandbox Code Playgroud)