-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* #82 - chore: 단순 패키지 정리 * #82 - feat: 파일 업로드를 위한 설정 추가 * #82 - feat: deploy 파일 변경 임시 파일 저장 경로를 설정하기 위해 * #82 - feat: S3에 저장, 조회, 삭제 로직 구현 * #82 - feat: 멤버의 프로필 저장 로직 구현 * #82 - feat: 에러 핸들러 추가 * #82 - feat: 파일 최대 사이즈 수정
- Loading branch information
Showing
13 changed files
with
229 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package cotato.bookitlist.config; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; | ||
import software.amazon.awssdk.auth.credentials.AwsCredentials; | ||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
|
||
@Configuration | ||
public class AwsS3Config { | ||
|
||
@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 AwsCredentials basicAWSCredentials() { | ||
return AwsBasicCredentials.create(accessKey, secretKey); | ||
} | ||
|
||
@Bean | ||
public S3Client s3Client(AwsCredentials awsCredentials) { | ||
return S3Client.builder().region(Region.of(region)) | ||
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials)).build(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...cotato/bookitlist/config/P6SpyConfig.java → .../bookitlist/config/p6spy/P6SpyConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...bookitlist/config/P6SpyEventListener.java → ...list/config/p6spy/P6SpyEventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ato/bookitlist/config/P6SpyFormatter.java → ...okitlist/config/p6spy/P6SpyFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/main/java/cotato/bookitlist/file/service/FileService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package cotato.bookitlist.file.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartException; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import software.amazon.awssdk.core.sync.RequestBody; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.services.s3.model.*; | ||
|
||
import java.io.IOException; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class FileService { | ||
|
||
private final S3Client s3Client; | ||
|
||
@Value("${cloud.aws.s3.bucket}") | ||
private String bucket; | ||
|
||
public String uploadFileToS3(Long memberId, String fileName, MultipartFile multipartFile) { | ||
String key = generateKey(memberId, fileName); | ||
|
||
PutObjectRequest putObjectRequest = PutObjectRequest.builder() | ||
.bucket(bucket) | ||
.key(key) | ||
.acl(ObjectCannedACL.BUCKET_OWNER_FULL_CONTROL) | ||
.build(); | ||
|
||
try { | ||
s3Client.putObject(putObjectRequest, RequestBody.fromInputStream(multipartFile.getInputStream(), multipartFile.getSize())); | ||
} catch (IOException ex) { | ||
log.error("파일 업로드 중 에러가 발생했습니다: {}", ex.getMessage()); | ||
throw new MultipartException("파일 업로드 중 에러가 발생했습니다.", ex); | ||
} catch (S3Exception ex) { | ||
log.error("S3에 파일을 업로드하는 중 에러가 발생했습니다: {}", ex.getMessage()); | ||
throw new MultipartException("S3에 파일을 업로드하는 중 에러가 발생했습니다.", ex); | ||
} | ||
|
||
return getS3FileUrl(key); | ||
} | ||
|
||
public String getS3FileUrl(String key) { | ||
try { | ||
return s3Client.utilities().getUrl(GetUrlRequest.builder().bucket(bucket).key(key).build()).toString(); | ||
} catch (NoSuchKeyException ex) { | ||
log.error("해당 키의 파일이 존재하지 않습니다: {}", key, ex); | ||
throw new RuntimeException("해당 키의 파일이 존재하지 않습니다.",ex); | ||
} catch (S3Exception ex) { | ||
log.error("S3에서 파일 URL을 가져오는 중 에러가 발생했습니다: {}", ex.getMessage()); | ||
throw new RuntimeException("S3에서 파일 URL을 가져오는 중 에러가 발생했습니다.", ex); | ||
} | ||
} | ||
|
||
public void deleteS3File(Long memberId, String fileName) { | ||
String key = generateKey(memberId, fileName); | ||
try { | ||
s3Client.deleteObject(DeleteObjectRequest.builder().bucket(bucket).key(key).build()); | ||
} catch (S3Exception ex) { | ||
log.error("S3에서 파일 삭제 중 에러가 발생했습니다: {}", ex.getMessage()); | ||
throw new RuntimeException("S3에서 파일 삭제 중 에러가 발생했습니다.", ex); | ||
} | ||
} | ||
|
||
private String generateKey(Long memberId, String fileName) { | ||
return String.format("member%s/%s", memberId, fileName); | ||
} | ||
|
||
|
||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/cotato/bookitlist/member/controller/MemberController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package cotato.bookitlist.member.controller; | ||
|
||
import cotato.bookitlist.config.security.jwt.AuthDetails; | ||
import cotato.bookitlist.member.dto.ProfileResponse; | ||
import cotato.bookitlist.member.service.MemberService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/members") | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@PatchMapping("/profiles") | ||
public ResponseEntity<ProfileResponse> uploadProfile( | ||
@RequestPart MultipartFile multipartFile, | ||
@AuthenticationPrincipal AuthDetails details | ||
) { | ||
return ResponseEntity.ok(ProfileResponse.of(memberService.uploadProfile(multipartFile, details.getId()))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/cotato/bookitlist/member/dto/ProfileResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package cotato.bookitlist.member.dto; | ||
|
||
public record ProfileResponse( | ||
String url | ||
) { | ||
|
||
public static ProfileResponse of(String url) { | ||
return new ProfileResponse(url); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/cotato/bookitlist/member/service/MemberService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package cotato.bookitlist.member.service; | ||
|
||
import cotato.bookitlist.file.service.FileService; | ||
import cotato.bookitlist.member.domain.Member; | ||
import cotato.bookitlist.member.repository.MemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class MemberService { | ||
|
||
private static final String PROFILE_FILE_NAME = "profile"; | ||
|
||
private final MemberRepository memberRepository; | ||
private final FileService fileService; | ||
|
||
public String uploadProfile(MultipartFile profile, Long memberId) { | ||
Member member = memberRepository.getReferenceById(memberId); | ||
|
||
String url = fileService.uploadFileToS3(member.getId(), PROFILE_FILE_NAME, profile); | ||
|
||
return member.updateProfileLine(url); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters