Spring Boot : 2.4.4 버전 입니다.
먼저 CKeditor와 AWS S3 버킷은 만들었다고 가정하겠습니다.
우선 기본적으로 CDN을 통해 CK editor를 붙이면 드래그&드롭기능은 있지만 이미지 업로드가 되지 않을텐데요. 먼저 이미지 업로드부터 활성화 시키겠습니다.
imageUploadUrl 이라는 키워드를 통해 드래그&드롭으로 이미지를 올릴 시 어떤 API로 보낼지 정할 수 있습니다. 저의 경우 /image/upload 입니다.
그 다음은 컨트롤러 부분을 보겠습니다.
CK Editor를 사용했다면서 왜 RestController있냐고 생각하실수도 있으신 분들을 위해 설명하겠습니다.
이미지 업로드를 하고 나면 정해진 형태의 json 양식으로 response를 보내주어야 CK Editor가 인식 할 수 있습니다.
response의 양식을 위와 같습니다.
그 다음은 Service 부분입니다.
코드가 길어 이미지 대신 코드블럭으로 대신하였습니다.
@Service
@RequiredArgsConstructor
@Slf4j
public class FileService {
private final AmazonS3Client amazonS3Client;
@Value("${cloud.aws.s3.bucket}")
private String bucket;
public FileUploadDTO fileUpload(MultipartFile upload, Principal principal) throws IOException {
File uploadFile = convert(upload).orElseThrow(() -> new IllegalArgumentException("MultipartFile -> File 전환실패."));
return upload(uploadFile, "static");
}
private FileUploadDTO upload(File uploadFile, String dir) {
String sourceName = uploadFile.getName();
String sourceExt = FilenameUtils.getExtension(sourceName).toLowerCase();
String fileName = dir + "/" + LocalDateTime.now().toString().concat(".").concat(sourceExt);
String uploadImageUrl = putS3(uploadFile, fileName);
removeNewFile(uploadFile);
return FileUploadDTO.builder()
.uploaded(true)
.fileName(fileName)
.url(uploadImageUrl)
.build();
}
private void removeNewFile(File targetFile) {
if (targetFile.delete()) {
log.info("파일이 삭제되었습니다.");
} else {
log.info("파일이 삭제되지 못했습니다.");
}
}
private String putS3(File uploadFile, String fileName) {
try {
amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (Exception e) {
log.error("이미지 s3 업로드 실패");
log.error(e.getMessage());
removeNewFile(uploadFile);
throw new RuntimeException();
}
return amazonS3Client.getUrl(bucket, fileName).toString();
}
private Optional<File> convert(MultipartFile file) throws IOException {
File convertFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
if (convertFile.createNewFile()) {
try (FileOutputStream fos = new FileOutputStream(convertFile)) {
fos.write(file.getBytes());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
}
코드에 대해 자세한 설명이 필요하신 분들은 https://jojoldu.tistory.com/300 이 글을 보시면 자세히 알 수 있습니다.
저는 위의 글과는 조금 다르게 환경설정을 했습니다. 위의 글에서는 aws.yml 파일을 따로 만들어서 accessKey와 secretKey를 등록을 해줬는데요 저같은 경우에는 로컬, develop 서버, product 서버의 환경이 다르다보니 각 서버별로 RDS를 연결시켜주어야 했습니다. 그러기 때문에 yml파일을 환경별로 세팅하여서 위의 글과는 다른 점이 있습니다. 물론 하나의 yml 파일에 ---로 구분지어 환경을 나눌수 있다고 하는데 아직 해보지 않아서 모르겠습니다. 추후 해본다음에 포스트하도록 하겠습니다.
다른점은 yml파일과 main 함수 부분입니다.
spring:
config:
activate:
on-profile: dev
mvc:
hiddenmethod:
filter:
enabled: false
datasource:
url: jdbc:mysql://${rds}:3306/board?autoReconnect=true&useUnicode=true&serverTimezone=UTC&characterEncoding=UTF8
username: ${username}
password: ${password}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
show_sql: true
format_sql: true
use_sql_comments: true
thymeleaf:
prefix: classpath:/templates/
suffix: .html
cache: false
loggin.level:
org.hibernate.SQL: debug
server:
port: 8888
cloud:
aws:
s3:
bucket: hese-board
region:
static: ap-northeast-2
credentials:
accessKey: ${accessKey}
secretKey: ${secretKey}
use-default-aws-credentials-chain: false
instance-profile: true
stack:
auto: false
accessKey와 secretKey 부분에 ${} 이렇게 되어있는걸 볼 수 있는데요 이렇게 해줌으로써 jar 파일을 실행할때 변수를 넘겨주어 acessKey와 secretKey를 설정해줄 수 있습니다.
제가 사용하는 명령어를 적어놓겠습니다.
java -Dspring.profiles.active=dev -jar /home/ubuntu/application/deploy/*.jar --rds=rds주소 --username=계정명 --password=비밀번호 --accessKey=액세스키 --secretKey=시크릿키
-Dspring.profiles.active로 사용할 application.yml 파일을 정해주고 뒤에 추가 변수로 전부 매핑시켜 줍니다.
'스프링 부트' 카테고리의 다른 글
스프링부트 게시판 API 만들기 - 4 (게시글 수정, 삭제 테스트 코드 작성) (0) | 2021.04.23 |
---|---|
스프링부트 게시판 API 만들기 - 3 (게시글 수정, 삭제 코드 작성) (0) | 2021.04.22 |
스프링부트 게시판 API 만들기 - 1 (환경 설정, 게시물 가져오기, 게시물 등록하기) (0) | 2021.04.21 |
Thymeleaf와 @ControllerAdvice를 활용하여 원하는 에러페이지 만들기 (0) | 2021.04.19 |
도커를 활용하여 배포 환경별로 설정하는법 (0) | 2021.04.15 |