Skip to content

Commit

Permalink
Merge pull request #26 from jwpark1211/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
jwpark1211 authored May 16, 2024
2 parents 2f0b424 + e60e7ed commit 10f4b47
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 10 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux' //webClient
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' //swagger
implementation 'org.springframework.boot:spring-boot-starter-data-redis' //redis
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' //s3
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/capstone/bookitty/common/S3Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package capstone.bookitty.common;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
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;

@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 AmazonS3Client amazonS3Client() {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

import static capstone.bookitty.domain.dto.MemberDTO.*;

Expand Down Expand Up @@ -81,15 +84,15 @@ public ResponseEntity<? extends BasicResponse> findAllMembers(
memberService.getAllMemberInfo(pageable)));
}

/* TODO : S3
@Operation(summary = "회원 프로필 업로드 / requestPart 이름 : profile")
@PostMapping(path = "/{id}/profile")
public ResponseEntity<? extends BasicResponse> updateMemberProfile(
@PathVariable("id") Long memberId,
@RequestPart(value = "profile") MultipartFile profileImg
) throws IOException {
memberService.updateProfile(memberId, profileImg);
return ResponseEntity.ok().build();
}*/
}

@Operation(summary = "회원 탈퇴")
@DeleteMapping(path = "/{id}")
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/capstone/bookitty/domain/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ public Member(String name, String email, String password, String profileImg,
this.password = password;
this.birthDate = birthDate;
this.createdAt = LocalDateTime.now();
this.profileImg = "https://bookitty-bucket.s3.ap-northeast-2.amazonaws.com/Jiji.jpeg";
this.grade = Grade.USER;
}

public void updateProfile(String profileImg){
this.profileImg = profileImg;
}

public void deleteProfile(){
this.profileImg = "https://bookitty-bucket.s3.ap-northeast-2.amazonaws.com/Jiji.jpeg";
}
}
32 changes: 24 additions & 8 deletions src/main/java/capstone/bookitty/domain/service/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;


import java.io.IOException;

import static capstone.bookitty.domain.dto.MemberDTO.*;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
private final S3Service s3Service;

@Transactional
public IdResponse saveMember(MemberSaveRequest request) {
Expand Down Expand Up @@ -58,16 +63,27 @@ public Page<MemberInfoResponse> getAllMemberInfo(Pageable pageable) {
.map(MemberInfoResponse::of);
}

/*TODO: S3 관련 처리
@Transactional
public void updateProfile(Long memberId, MultipartFile profileImg)
throws MultipartException {
if(profileImg.isEmpty())
throw new MultipartException("The file is not valid.");
Member member = memberRepository.findById(memberId)
.orElseThrow(()-> new EntityNotFoundException("member not found."));
member.updateImg(url);
}*/
throws MultipartException, IOException {
try {
if (profileImg.isEmpty()) {
throw new MultipartException("The file is not valid.");
}
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new EntityNotFoundException("member not found."));
String imageUrl = s3Service.uploadFile(profileImg);
member.updateProfile(imageUrl);
} catch (MultipartException e) {
throw e;
} catch (EntityNotFoundException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("An unexpected error occurred while updating the profile.", e);
}
}

//TODO : SPRING SECURITY AUTHORITY SETTING
@Transactional
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/capstone/bookitty/domain/service/S3Service.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package capstone.bookitty.domain.service;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@Service
@RequiredArgsConstructor
public class S3Service {
@Value("${cloud.aws.s3.bucket}")
private String bucket;
private final AmazonS3 amazonS3;

public String uploadFile(MultipartFile multipartFile) throws IOException {
String fileName = multipartFile.getOriginalFilename();

//파일 형식 구하기
String ext = fileName.split("\\.")[1];
String contentType = "";

//content type을 지정해서 올려주지 않으면 자동으로 "application/octet-stream"으로 고정이
// 돼서 링크 클릭시 웹에서 열리는게 아니라 자동 다운이 시작됨.
switch (ext) {
case "jpeg":
contentType = "image/jpeg";
break;
case "png":
contentType = "image/png";
break;
case "txt":
contentType = "text/plain";
break;
case "csv":
contentType = "text/csv";
break;
}

try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);

amazonS3.putObject(new PutObjectRequest(bucket, fileName, multipartFile.getInputStream(), metadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (AmazonServiceException e) {
e.printStackTrace();
} catch (SdkClientException e) {
e.printStackTrace();
}

//object 정보 가져오기
ListObjectsV2Result listObjectsV2Result = amazonS3.listObjectsV2(bucket);
List<S3ObjectSummary> objectSummaries = listObjectsV2Result.getObjectSummaries();

for (S3ObjectSummary object: objectSummaries) {
System.out.println("object = " + object.toString());
}
return amazonS3.getUrl(bucket, fileName).toString();
}

public void deleteImage(String filename){
amazonS3.deleteObject(new DeleteObjectRequest(bucket,filename));
}

}

0 comments on commit 10f4b47

Please sign in to comment.