diff --git "a/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/S3Controller_chaiwonHwang.java" "b/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/S3Controller_chaiwonHwang.java" new file mode 100644 index 0000000..dbe65ff --- /dev/null +++ "b/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/S3Controller_chaiwonHwang.java" @@ -0,0 +1,64 @@ +package ServerStudy5Cloud.ServerStudy5Cloud.Controller; + +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.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.server.ResponseStatusException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +// https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3.html +// https://growth-coder.tistory.com/116 +@Controller +@RequiredArgsConstructor +public class S3Controller { + + private final AmazonS3 amazonS3; + + @Value("${cloud.aws.s3.bucket}") + private String bucketName; + + @GetMapping("/") + public String listFiles(Model model) { + //getUrl로 객체 URL 가져온 후, List에 넣어 index.html에 반환하기 + List fileUrls = new ArrayList<>(); + List objectSummaries = amazonS3.listObjects(bucketName).getObjectSummaries(); + for (S3ObjectSummary os : objectSummaries) { + String url = "https://" + bucketName + ".s3.amazonaws.com/" + os.getKey(); + fileUrls.add(url); + } + model.addAttribute("fileUrls", fileUrls); + return "index"; + } + + @PostMapping("/upload") + public String uploadFile(@RequestParam("file") MultipartFile file) { + //putObject와 setObjectAcl로 이미지 업로드하고 ACL 퍼블릭으로 만들기 + // 파일 업로드 로직 + String fileName = file.getOriginalFilename(); + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(file.getSize()); + metadata.setContentType(file.getContentType()); + + try { + amazonS3.putObject(bucketName, fileName, file.getInputStream(), metadata); + } catch (IOException e) { + throw new RuntimeException(e); + } + amazonS3.setObjectAcl(bucketName, fileName, CannedAccessControlList.PublicRead); + return "redirect:/"; + + } +} \ No newline at end of file diff --git "a/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_5\354\243\274\354\262\264_\352\263\274\354\240\234.md" "b/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_5\354\243\274\354\262\264_\352\263\274\354\240\234.md" new file mode 100644 index 0000000..2a90b32 --- /dev/null +++ "b/5\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_5\354\243\274\354\262\264_\352\263\274\354\240\234.md" @@ -0,0 +1,66 @@ +### 과제링크 + +https://drive.google.com/file/d/11ZL6ydk9WMiko-jp4E0RmoXrEZvhr-PN/view?usp=sharing + +--- + +### 파일 보기 구현 +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/e49f5e4f-b867-4ec2-8ed1-8132648b18ff) + +--- +### 파일 업로드 구현 + +``` +@PostMapping("/upload") + public String uploadFile(@RequestParam("file") MultipartFile file, Model model) { + //putObject와 setObjectAcl로 이미지 업로드하고 ACL 퍼블릭으로 만들기 + if (file.isEmpty()) { + model.addAttribute("message", "업로드할 파일이 없습니다."); + return "errorPage"; // 에러 메시지를 표시할 뷰 이름 + } + + try { + // 파일 업로드 로직 + String fileName = file.getOriginalFilename(); + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(file.getSize()); + metadata.setContentType(file.getContentType()); + + amazonS3.putObject(bucketName, fileName, file.getInputStream(), metadata); + amazonS3.setObjectAcl(bucketName, fileName, CannedAccessControlList.PublicRead); + return "redirect:/"; + + } catch (Exception e) { + // 예외 메시지를 모델에 추가 + model.addAttribute("message", "업로드 중 오류 발생: " + e.getMessage()); + return "errorPage"; // 에러 메시지를 표시할 뷰 이름 + } + + } +``` + + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/b85ab488-db69-4f2b-8ad8-f9ff94fb9d9d) + +에러 확인을 위해 errorPage.html을 추가하고 웹페이지에 에러가 출력되도록 설정해보았지만 + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/e046ee55-5af4-4338-b4a4-ab0ab6ecec55) + +여전히 같은 white label 에러가 나는 상황이다. + + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/0f9261c6-b74b-4935-afa7-4733eb024b9b) + +이것저것 시도해보았는데 허무하게도(?) 사진 사이즈가 너무 컸다는 것을 알게되었다... + +인터넷에서 적당히 작은 사진을 찾아 업로드해보았더니 아주 잘 올라간다... + + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/c6347889-4f61-4f91-bff1-82bcaae76ed1) + +--- +**참고** + +- https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3.html + +- https://growth-coder.tistory.com/116 diff --git "a/6\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_6\354\243\274\354\260\250_\352\263\274\354\240\234.md" "b/6\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_6\354\243\274\354\260\250_\352\263\274\354\240\234.md" new file mode 100644 index 0000000..4c09618 --- /dev/null +++ "b/6\354\243\274\354\260\250 Server S-Day \352\263\274\354\240\234/\355\231\251\354\261\204\354\233\220_6\354\243\274\354\260\250_\352\263\274\354\240\234.md" @@ -0,0 +1,33 @@ +## 6주차 과제 + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/c1f8d221-6595-4483-a1c2-2836b7ddaf2f) + +`Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure` 이라는 오류가 계속 발생했다. +main을 실행하면 아래 사진과 같이 `application.yml` 파일이 리셋된다. + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/377ca9d8-cd72-4379-bdd5-0c68ce27c55b) + + + +**사용한 VPC** + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/565eab2b-dc54-478e-bdc4-f32349dc8406) + +**사용한 라우팅 테이블** + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/f5d8a420-e408-49b2-94a4-945e5a42d459) + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/a402f4d6-6d2b-4eae-8bc8-ceaa1dfead6b) + +**보안그룹 설정** + +인바운드 규칙 설정 + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/3deda922-c8e0-4951-bc30-cce1e7cab9f0) + +아웃바운드 규칙 설정 + +![image](https://github.com/GDSC-Ewha-5th/GDSC-Server-5th/assets/90598552/4261324e-df98-4151-aecd-760336c35004) + + +