IAM 생성
보안 자격증명 (엑세스 키 발급)
application.yml 작성
cloud:
aws:
credentials:
access-key: {다운받은 키 파일 중 Access Key ID}
secret-key: {다운받은 키 파일 중 Secret Access Key}
region:
static: ap-northeast-2
stack:
auto: false
S3 bucket 생성
S3 버킷 정책 설정
# 버킷 설정
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::버킷 이름/*"
}
]
}
# CORS 설정
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["x-amz-server-side-encryption", "x-amz-request-id", "x-amz-id-2"],
"MaxAgeSeconds": 3000
}
]
S3Config 설정
package com.likelion.catdogpia.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// application.yml(application-secret) 파일에서 설정하였던 값들을 가져와, 이를 통하여 AmazonS3Client를 Bean 등록
@Configuration
public class S3Config {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3 amazonS3Client() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
}
AmazonS3Client
: Amazon S3 서비스와 상호 작용하는 클라이언트 객체로 S3 서비스에 파일을 업로드, 다운로드, 삭제 등의 작업을 수행하는 데 사용BasicAWSCredentials
: AWS 계정의 액세스 키와 시크릿 키를 사용하여 AWS 서비스에 액세스하는 인증 정보AmazonS3ClientBuilder
: AmazonS3 클라이언트를 생성하기 위한 빌더 클래스 AWS 설정 및 인증 정보, 지역(region) 등을 설정하여 클라이언트를 생성withCredentials
: 생성된 클라이언트에 인증 정보를 제공withRegion
: Amazon S3의 리전(region)을 설정<script>
//== 등록 요청 ==//
$("#submitBnt").on("click", function() {
const productData = {
categoryId: $("#selectedSubCategory :selected").val(),
name: $("#name").val(),
status: $("#status").val(),
price: parseInt($("#price").val()),
productOptionList: []
};
const formData = new FormData();
const mainImg = $("#mainImg")[0].files[0];
formData.append("mainImg", mainImg);
const detailImg = $("#detailImg")[0].files[0];
formData.append("detailImg", detailImg);
$("#items-container .item").each(function() {
const color = $(this).find("input.color").val();
const size = $(this).find("select.size").val();
const stock = $(this).find("input.stock").val();
if (color && size && stock) {
const optionData = {
color: color,
size: size,
stock: parseInt(stock)
};
productData.productOptionList.push(optionData);
}
});
formData.append("productDto", JSON.stringify(productData));
$.ajax({
type: "POST",
url: "/admin/products/create",
contentType: false,
processData: false,
enctype: 'multipart/form-data',
data: formData,
success: function(response) {
console.log("Product created successfully!");
window.location.href = "/admin/products";
},
error: function(error) {
console.error("Error creating product:", error);
}
});
});
</script>
// Controller
public String productCreate(
@RequestParam("mainImg") MultipartFile mainImg,
@RequestParam("detailImg") MultipartFile detailImg,
@RequestBody ProductDto productDto
) {
// Controller 수정
public String productCreate(
@RequestParam("mainImg") MultipartFile mainImg,
@RequestParam("detailImg") MultipartFile detailImg,
@RequestParam("productDto") String productDto
) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
ProductDto product = objectMapper.readValue(productDto, ProductDto.class);
log.info("product toString : " + product.toString());
}