Skip to content
Mambo edited this page Nov 28, 2025 · 10 revisions

파일 객체를 업로드할 수 있다.

SdkHttpResponse sdkHttpResponse = s3.putObject(
            builder -> builder.bucket(bucket).key(key).storageClass(StorageClass.STANDARD_IA)
                .contentType("image/jpeg").contentLength((long) bytes.length),
            RequestBody.fromBytes(bytes)).sdkHttpResponse();

boolean successful = sdkHttpResponse.isSuccessful();
HttpStatus httpStatus = HttpStatus.valueOf(sdkHttpResponse.statusCode());

S3Presigner 로 미리 서명된 URL을 생성하면 클라이언트 측에서 별도로 파일 업로드도 가능

DeleteObjectResponse response = s3.deleteObject(builder -> builder.bucket(bucket).key(key));
boolean successful = response.sdkHttpResponse().isSuccessful();

업로드된 파일 객체의 메타데이터를 조회할 때 사용할 수 있는데 파일 형식(Content-Type)이나 파일 크기(Content-Length)를 확인하거나 파일이 존재하는지 여부를 검사할 수 있다.

객체 메타데이터를 포함하여 바이너리 파일까지 가져올 수 있다.

ResponseBytes<GetObjectResponse> response = s3.getObjectAsBytes(builder -> builder.bucket(bucket).key(key));
byte[] bytes = response.asByteArray();
Long contentLength = response.response().contentLength();

🔥 s3:ListBucket 권한은 사용자가 Amazon S3 ListObjectsV2 작업을 사용할 수 있도록 허용합니다.

ListObjectsV2Response listObjectsV2 = s3.listObjectsV2(builder -> builder.bucket(bucket).prefix(prefix));
List<S3Object> s3Objects = listObjectsV2.contents();

서버에서는 서명(Signature) 파라미터가 포함된 URL을 발급하고 클라이언트에서 파일을 직접 업로드하는 방식으로 S3 버킷 권한에 업로드를 시도하는 호스트에 대한 CORS 설정이 필요하다.

PresignedPutObjectRequest request = s3Presigner.presignPutObject(builder ->
    builder.putObjectRequest(PutObjectRequest.builder().bucket(bucket).key(key).contentLength(fileSize).build())
        .signatureDuration(Duration.ofMinutes(5)));

return request.url().toString();

presignPutObject 함수는 멀티파트 요청이 아닌 단일 파일 업로드를 위한 URL 이므로 클라이언트에서는 octet-stream 으로 전달하면 된다.

async uploadFile({ fileName, fileSize }) {
    const response = await axios.post(
        '/api/files',
        { fileName, fileSize }
    );
    return response.data;
},

const uploadFile = async (file) => {
    const reader = new FileReader();
    reader.onload = async (event) => {
        const fileName = file.name
        const fileSize = file.size
        
        const url = await uploadFile({ fileName, fileSize })
        const blob = new Blob([event.target.result], { type: file.type });
        const res = await axios.create().put(url, blob, { headers: { 'Content-Type': 'application/octet-stream' } })
    };
    reader.readAsArrayBuffer(file);
}
🔥 S3 버킷에 CORS 설정이 올바르지 않은 경우
Access to XMLHttpRequest at 'https://[bucket].s3.ap-northeast-2.amazonaws.com/[key]?X-Amz-Security-Token=&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20251128T084828Z&X-Amz-SignedHeaders=content-length%3Bhost&X-Amz-Expires=300&X-Amz-Credential=ASIAZ7SALCZRZHB2R557%2F20251128%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Signature=b723361c965723f4ee4f7d9fd2c6e221ba8582282f964eea3ea2af3db5ce15fd'
from origin 'https://[host]' has been blocked by CORS policy: Response to preflight request doesn't pass access control
check: No 'Access-Control-Allow-Origin' header is present on the requested resource
🔥 인증 헤더가 별도로 포함된 경우
<?xml version="1.0" encoding="UTF-8"?>
<Error>
	<Code>InvalidArgument</Code>
	<Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
	<ArgumentName>Authorization</ArgumentName>
	<ArgumentValue>...</ArgumentValue>
	<RequestId>BR3A8GYCW4DHZ6R7</RequestId>
	<HostId>LKr5YrVAEImerAETv66OOabsrP3NqE6F2O/T0LFafhrkalNyrGkze1uuFX9KTA86j+vok2o+miQPBnRz5XOAuw7L7Voxeq43</HostId>
</Error>

Clone this wiki locally