Skip to content

Commit

Permalink
✨ [FEATURE] AWS S3 추가 (#34)
Browse files Browse the repository at this point in the history
Co-authored-by: marooo326 <[email protected]>
  • Loading branch information
seheonnn and kimday0326 authored Jan 23, 2024
1 parent 1f25a65 commit 599cbb8
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 3 deletions.
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,16 @@ dependencies {

// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

tasks.named('test') {
useJUnitPlatform()
}

// enable plain.jar
jar{
enabled=false
jar {
enabled = false
}
56 changes: 56 additions & 0 deletions src/main/java/com/sponus/sponusbe/domain/s3/S3Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.sponus.sponusbe.domain.s3;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

import jakarta.annotation.PostConstruct;
import lombok.Getter;

@Configuration
@Getter
public class S3Config {

private AWSCredentials awsCredentials;

@Value("${cloud.aws.credentials.accessKey}")
private String accessKey;

@Value("${cloud.aws.credentials.secretKey}")
private String secretKey;

@Value("${cloud.aws.region.static}")
private String region;

@Value("${cloud.aws.s3.bucket}")
private String bucket;

@Value("${cloud.aws.s3.folder}")
private String folder;

@PostConstruct
public void init() {
this.awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
}

@Bean
public AmazonS3 amazonS3() {
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}

@Bean
public AWSCredentialsProvider awsCredentialsProvider() {
return new AWSStaticCredentialsProvider(awsCredentials);
}
}
42 changes: 42 additions & 0 deletions src/main/java/com/sponus/sponusbe/domain/s3/S3Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.sponus.sponusbe.domain.s3;

import java.util.List;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.sponus.sponusbe.global.common.ApiResponse;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/s3")
public class S3Controller {

private final S3Service s3Service;

@PostMapping(value = "/uploadImage", consumes = "multipart/form-data")
public ApiResponse<String> uploadImage(@RequestPart(value = "file", required = false) MultipartFile file) {
return ApiResponse.onSuccess(s3Service.uploadFile(file));
}

@DeleteMapping(value = "/deleteImage", consumes = "multipart/form-data")
public ApiResponse<String> deleteImage(@RequestPart(value = "path", required = false) String path) {
String image = path.substring(path.lastIndexOf('/') + 1);
return ApiResponse.onSuccess(s3Service.deleteImage(image));
}

@PostMapping(value = "/uploadImages", consumes = "multipart/form-data")
public ApiResponse<List<String>> uploadImages(
@RequestPart(value = "files", required = false) List<MultipartFile> files) {
return ApiResponse.onSuccess(s3Service.uploadFiles(files));
}

}
59 changes: 59 additions & 0 deletions src/main/java/com/sponus/sponusbe/domain/s3/S3Service.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.sponus.sponusbe.domain.s3;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@RequiredArgsConstructor
public class S3Service {

private final AmazonS3 amazonS3;

private final S3Config s3Config;

public String uploadFile(MultipartFile file) {
String filePath =
UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(
new PutObjectRequest(s3Config.getBucket(), s3Config.getFolder() + filePath, file.getInputStream(),
metadata));
} catch (IOException e) {
log.error("error at AmazonS3Manager uploadFile : {}", (Object)e.getStackTrace());
}

return amazonS3.getUrl(s3Config.getBucket(), filePath).toString();
}

public String deleteImage(String image) {
amazonS3.deleteObject(s3Config.getBucket(), s3Config.getFolder() + image);
return "삭제 성공";
}

public List<String> uploadFiles(List<MultipartFile> files) {
List<String> fileUrls = new ArrayList<>();

files.stream().map(file -> {
fileUrls.add(uploadFile(file));
return fileUrls;
}).collect(Collectors.toList());
return fileUrls;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
public class SecurityConfig {

private final String[] swaggerUrls = {"/swagger-ui/**", "/v3/**"};
private final String[] authUrls = {"/", "/api/v1/organizations/join/**", "/api/v1/organizations/login/**"};
private final String[] authUrls = {"/", "/api/v1/organizations/join/**", "/api/v1/organizations/login/**",
"/api/v1/s3/**"};
private final String[] allowedUrls = Stream.concat(Arrays.stream(swaggerUrls), Arrays.stream(authUrls))
.toArray(String[]::new);

Expand Down

0 comments on commit 599cbb8

Please sign in to comment.