Java S3 API:文件在 S3 浏览器中未正确显示

问题描述

我正在使用 this S3 library文件存储到 S3 存储桶中。

代码如下:

DocumentService.java

    /**
     * Persists document information in Object store
     *
     * @param documentDto document upload data
     * @return id of uploaded document
     * @throws GenericException on error
     */
    @Transactional
    public UUID uploadDocument(DocumentDto documentDto) throws GenericException {
        validationService.validateAndThrowException(documentDto);

        String uuid = randomUUID().toString()
        multipartfile documentFile = documentDto.getFile();
        String documentRefKey = "SFI_" + currentDate() + "/" + uuid + "/";

        // Store the document in s3 bucket
        s3Client.putObject(createPutDocumentFileRequest(documentFile,documentRefKey));

        return uuid;
    }

    /**
     * Creates put request for object store.
     *
     * @param document document
     * @param documentRefKey document reference key
     * @return put object request
     */
    private PutObjectRequest createPutDocumentFileRequest(multipartfile document,String documentRefKey) {
        S3ObjectMetadata Metadata = new S3ObjectMetadata();
        Metadata.addUserMetadata("fileName",document.getFileName());
        Metadata.setContentType(document.getFileType());
        PutObjectRequest req = new PutObjectRequest(bucketName,documentRefKey,document.getInputStream());
        req.withObjectMetadata(Metadata);

        return req;
    }

但是,如果我查看我的桶,它是这样的:

enter image description here

不知道为什么会这样。

解决方法

在您的代码中的某处,可能在 currentDate 方法中,除了提供像 ddMMyyyy 这样的日期模式之外,您似乎还在日期和日期之间包含了一个 / 字符构造 documentRefKey S3 对象键时的 UUID。它将如下所示:

SFI_11022021/<the generated uuid>

当您将此对象放入 S3 存储桶时,AWS 会解释为它应该创建一个“类似文件夹”的结构,并按 / 字符拆分信息:

SFI_11022021
    <the generated uuid>

根据 AWS documentation,例如,给定键 s3-dg.pdfDevelopment/Projects.xls 等:

控制台使用键名前缀(Development/Finance/Private/)和分隔符('/')来呈现文件夹结构。 s3-dg.pdf 键没有前缀,因此它的对象直接出现在存储桶的根级别。如果您打开 Development/ 文件夹,您会在其中看到 Projects.xlsx 对象。

  • Amazon S3 支持存储桶和对象,并且没有层次结构。但是,通过在对象键名称中使用前缀和分隔符,Amazon S3 控制台和 AWS 开发工具包可以推断层次结构并引入文件夹的概念。
,

我终于自己解决了这个问题。真正的技巧是在 key 中包含完整的文件名。 enter image description here

为了调试问题,我查看了我通过 S3 手动上传的文件的所有属性和元信息,并将其与以编程方式上传的文件相匹配。 这导致在 key 引用中发现不匹配。

我很惊讶文档中没有明确提到它。这是固定代码:


    /**
     * Persists document information in Object store
     *
     * @param documentDto document upload data
     * @return id of uploaded document
     */
    @Transactional
    public UUID uploadDocument(DocumentDto documentDto) {
        validationHandler.validate(documentDto);

        String uuid = randomUUID().toString()
        MultipartFile documentFile = documentDto.getFile();
        String documentRefPath = "SFI_" + currentDate() + "/" + uuid + "/";

        // Store the converted document in s3 bucket
        s3Client.putObject(createPutDocumentFileRequest(documentFile,documentRefPath));

        return uuid;
    }


    /**
     * Creates put request for object store.
     *
     * @param targetFile document file
     * @param documentRefPath document reference key
     * @return put object request
     */
    private PutObjectRequest createPutDocumentFileRequest(MultipartFile documentFile,String documentRefPath) {
        String fileName = documentFile.getFileName();
        String key = documentRefPath + fileName; // <-- the missing puzzle piece

        S3ObjectMetadata metadata = new S3ObjectMetadata();
        metadata.addUserMetadata("fileName",fileName);
        metadata.setContentType(documentFile.getFileType());
        PutObjectRequest req = new PutObjectRequest(bucketName,key,documentFile);
        req.withObjectMetadata(metadata);

        return req;
    }