How can I set s3 object meta data with presigned url?

Viewed 586

Firstly, sorry for poor english.

I'm using s3 bucket. Because frontend(react) and backend(spring boot) are separated, I tried to make it possible to upload file directly from frontend using presigned url that AWS SDK provided.

How Can I set MetaData of S3 Bucket Objet?

Uploading using SDK from backend was simple. All I had to do is to add some code like below.

val objectMetadata = ObjectMetadata()
objectMetadata.contentDisposition = "attachment; filename=\"${urlEncodedOriginalFileName}\"; filename*=UTF-8'${urlEncodedOriginalFileName}'"
objectMetadata.contentLength = file.bytes.size.toLong()

But I'm struggling with adding Object MetaData using preSignedURL. What is the exact way to put Object MetaData to uploaded file(S3 Object)?

I tried like this way. But It didn't work.

package com.sunnyfactory.haeorum.controller.share

import com.amazonaws.HttpMethod
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.Headers
import com.amazonaws.services.s3.model.CannedAccessControlList
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest
import com.amazonaws.services.s3.model.ResponseHeaderOverrides
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.RequestEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*

@RestController
@RequestMapping("/api/attachment")
class AttachmentController (
        private val amazonS3: AmazonS3
){
    @Value("\${amazon.aws.s3.bucket-name}")
    lateinit var bucketName: String

    @GetMapping("/upload-pre-signed-url")
    fun getUploadPreSignedUrl(): Map<String, String> {
        val expiration = Date()
        expiration.time = expiration.time + 1000 * 60 * 30

        val uuid = UUID.randomUUID().toString().toLowerCase();
        val year = SimpleDateFormat("YYYY").format(Date())
        val date = SimpleDateFormat("MM-dd").format(Date())
        val awsS3Key = "photo/${year}/${date}/${uuid}"

        val generatedPresignedUrlRequest = GeneratePresignedUrlRequest(bucketName, awsS3Key)
                .withMethod(HttpMethod.PUT)
                .withExpiration(expiration)

        generatedPresignedUrlRequest.addRequestParameter(
                Headers.S3_CANNED_ACL,
                CannedAccessControlList.PublicRead.toString()
        )

        generatedPresignedUrlRequest.addRequestParameter(
                Headers.CONTENT_DISPOSITION,
                "attachment; filename=\"abc.jpg\""
        )

        val responseHeader = ResponseHeaderOverrides()
        responseHeader.withContentType("application/octet-stream")
        responseHeader.withContentDisposition("attachment; filename=\"abc.jpg\"")

        generatedPresignedUrlRequest.withResponseHeaders(responseHeader)

        val preSignedUrl = amazonS3.generatePresignedUrl(
                generatedPresignedUrlRequest
        )

        val returnValue = mutableMapOf<String, String>()

        returnValue["preSignedUrl"] = preSignedUrl.toString()
        returnValue["awsS3Key"] = awsS3Key

        return returnValue
    }
}
export const getUploadPresignedUrl = () => nonLoadingAxios.get(authUrl + '/upload-pre-signed-url');
export const uploadFileToAws = (preSignedUrl: string, file: File, renewUploadProgress?: (loaded:number, total: number)=>void, cancelToken?: CancelTokenSource) => {
    const uriEncodedFileName = encodeURI(file.name)
    return vanillaAxios.put(
        preSignedUrl,
        file,
        {
            headers: new Headers({
                'Content-Type': 'image/*',
                'Content-Disposition': 'attachment;' //It doesn't work.
            }),
            onUploadProgress: (progress) => {
                if(renewUploadProgress){
                    renewUploadProgress(progress.loaded, progress.total)
                }
            },
            cancelToken: cancelToken?.token
        },
    )
}
0 Answers
Related