forked from codesquad-members-2024/issue-tracker
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
219 additions
and
5 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
15 changes: 12 additions & 3 deletions
15
be/issue_tracker/src/main/java/team1/issuetracker/HomeController.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 |
---|---|---|
@@ -1,18 +1,27 @@ | ||
package team1.issuetracker; | ||
|
||
import jakarta.servlet.http.HttpServletResponse; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import team1.issuetracker.util.S3Util; | ||
|
||
import java.io.IOException; | ||
|
||
@RestController | ||
@RequestMapping("/") | ||
@RequiredArgsConstructor | ||
public class HomeController { | ||
|
||
private final S3Util s3Util; | ||
|
||
@GetMapping("/github") | ||
public void redirectToGithub(HttpServletResponse httpServletResponse) throws IOException { | ||
httpServletResponse.sendRedirect("https://github.com/codesquad-masters2024-team01/issue-tracker"); | ||
} | ||
|
||
@PostMapping("/upload") | ||
public String uploadImage(@RequestPart(value = "image", required = false) MultipartFile image){ | ||
return s3Util.upload(image); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
be/issue_tracker/src/main/java/team1/issuetracker/config/S3Config.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,29 @@ | ||
package team1.issuetracker.config; | ||
|
||
import com.amazonaws.auth.AWSStaticCredentialsProvider; | ||
import com.amazonaws.auth.BasicAWSCredentials; | ||
import com.amazonaws.regions.Regions; | ||
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; | ||
|
||
@Configuration | ||
public class S3Config { | ||
|
||
@Value("${aws.s3.accessKey}") | ||
private String accessKey; | ||
@Value("${aws.s3.secretKey}") | ||
private String secretKey; | ||
|
||
@Bean | ||
public AmazonS3 amazonS3Client(){ | ||
return AmazonS3ClientBuilder.standard() | ||
.withCredentials( | ||
new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)) | ||
) | ||
.withRegion(Regions.AP_NORTHEAST_2) | ||
.build(); | ||
} | ||
} |
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
95 changes: 95 additions & 0 deletions
95
be/issue_tracker/src/main/java/team1/issuetracker/util/S3Util.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,95 @@ | ||
package team1.issuetracker.util; | ||
|
||
import com.amazonaws.services.s3.AmazonS3; | ||
import com.amazonaws.services.s3.model.CannedAccessControlList; | ||
import com.amazonaws.services.s3.model.ObjectMetadata; | ||
import com.amazonaws.services.s3.model.PutObjectRequest; | ||
import com.amazonaws.util.IOUtils; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.UUID; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class S3Util { | ||
private final AmazonS3 amazonS3; | ||
|
||
@Value("${aws.s3.bucketName}") | ||
private String bucketName; | ||
|
||
public String upload(MultipartFile image) { | ||
//입력받은 이미지 파일이 빈 파일인지 검증 | ||
if (image.isEmpty() || Objects.isNull(image.getOriginalFilename())) { | ||
throw new IllegalArgumentException(); | ||
} | ||
//uploadImage를 호출하여 S3에 저장된 이미지의 public url을 반환한다. | ||
return this.uploadImage(image); | ||
} | ||
|
||
private String uploadImage(MultipartFile image) { | ||
this.validateImageFileExtention(image.getOriginalFilename()); | ||
try { | ||
return this.uploadImageToS3(image); | ||
} catch (IOException e) { | ||
throw new IllegalArgumentException(e); | ||
} | ||
} | ||
|
||
private void validateImageFileExtention(String filename) { | ||
int lastDotIndex = filename.lastIndexOf("."); | ||
if (lastDotIndex == -1) { | ||
throw new IllegalArgumentException("-1"); | ||
} | ||
|
||
String extention = filename.substring(lastDotIndex + 1).toLowerCase(); | ||
List<String> allowedExtentionList = Arrays.asList("jpg", "jpeg", "png", "gif"); | ||
|
||
if (!allowedExtentionList.contains(extention)) { | ||
throw new IllegalArgumentException("extention"); | ||
} | ||
} | ||
|
||
private String uploadImageToS3(MultipartFile image) throws IOException { | ||
String originalFilename = image.getOriginalFilename(); //원본 파일 명 | ||
String extention = originalFilename.substring(originalFilename.lastIndexOf(".")); //확장자 명 | ||
|
||
String s3FileName = UUID.randomUUID().toString().substring(0, 10) + originalFilename; //변경된 파일 명 | ||
|
||
InputStream is = image.getInputStream(); | ||
byte[] bytes = IOUtils.toByteArray(is); //image를 byte[]로 변환 | ||
|
||
ObjectMetadata metadata = new ObjectMetadata(); //metadata 생성 | ||
metadata.setContentType("image/" + extention); | ||
metadata.setContentLength(bytes.length); | ||
|
||
//S3에 요청할 때 사용할 byteInputStream 생성 | ||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); | ||
|
||
try { | ||
//S3로 putObject 할 때 사용할 요청 객체 | ||
//생성자 : bucket 이름, 파일 명, byteInputStream, metadata | ||
PutObjectRequest putObjectRequest = | ||
new PutObjectRequest(bucketName, s3FileName, byteArrayInputStream, metadata) | ||
.withCannedAcl(CannedAccessControlList.PublicRead); | ||
|
||
//실제로 S3에 이미지 데이터를 넣는 부분이다. | ||
amazonS3.putObject(putObjectRequest); // put image to S3 | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException(e); | ||
} finally { | ||
byteArrayInputStream.close(); | ||
is.close(); | ||
} | ||
|
||
return amazonS3.getUrl(bucketName, s3FileName).toString(); | ||
} | ||
} |
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