Skip to content

Commit

Permalink
Merge pull request #47 from Move-Log/develop
Browse files Browse the repository at this point in the history
Merge develop to main
EunbeenDev authored Jan 13, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 19ac66b + 6356304 commit cc46fdd
Showing 21 changed files with 329 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
@Service
@RequiredArgsConstructor
@Slf4j
public class HeadlineGeneratorService {
public class HeadLineGeneratorService {

private final GptService gptService;

59 changes: 50 additions & 9 deletions src/main/java/com/movelog/domain/news/application/NewsService.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package com.movelog.domain.news.application;

import com.movelog.domain.news.domain.News;
import com.movelog.domain.news.domain.repository.NewsRepository;
import com.movelog.domain.news.dto.request.CreateNewsReq;
import com.movelog.domain.news.dto.request.NewsHeadLineReq;
import com.movelog.domain.news.dto.response.HeadLineRes;
import com.movelog.domain.record.domain.Keyword;
import com.movelog.domain.record.domain.VerbType;
import com.movelog.domain.record.exception.KeywordNotFoundException;
import com.movelog.domain.record.repository.KeywordRepository;
import com.movelog.domain.user.application.UserService;
import com.movelog.domain.user.domain.User;
import com.movelog.domain.user.domain.repository.UserRepository;
import com.movelog.domain.user.exception.UserNotFoundException;
import com.movelog.global.DefaultAssert;
import com.movelog.global.config.security.token.UserPrincipal;
import com.movelog.global.util.S3Util;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Optional;
@@ -20,24 +27,58 @@
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NewsService {
private final HeadlineGeneratorService headlineGeneratorService;
private final HeadLineGeneratorService headLineGeneratorService;
private final UserService userService;
private final UserRepository userRepository;
private final KeywordRepository keywordRepository;
private final NewsRepository newsRepository;
private final S3Util s3Util;

public List<HeadLineRes> createHeadLine(UserPrincipal userPrincipal, NewsHeadLineReq newsHeadLineReq) {
public List<HeadLineRes> createHeadLine(UserPrincipal userPrincipal, Long keywordId, NewsHeadLineReq newsHeadLineReq) {
User user = validateUser(userPrincipal);
// id가 5인 유저 정보(테스트용)
// User user = userRepository.findById(5L).orElseThrow(UserNotFoundException::new);
Keyword keyword = validateKeyword(keywordId);
String option = newsHeadLineReq.getOption();
String verb = newsHeadLineReq.getVerb();
String noun = newsHeadLineReq.getNoun();
return headlineGeneratorService.generateHeadLine(option, verb, noun);
String verb = VerbType.getStringVerbType(keyword.getVerbType());
String noun = keyword.getKeyword();

return headLineGeneratorService.generateHeadLine(option, verb, noun);
}

@Transactional
public void createNews(UserPrincipal userPrincipal, Long keywordId, CreateNewsReq createNewsReq, MultipartFile img) {
User user = validateUser(userPrincipal);
// id가 5인 유저 정보(테스트용)
// User user = userRepository.findById(5L).orElseThrow(UserNotFoundException::new);
Keyword keyword = validateKeyword(keywordId);

String newsImgUrl = s3Util.uploadToNewsFolder(img);

News news = News.builder()
.headLine(createNewsReq.getHeadLine())
.newsUrl(newsImgUrl)
.keyword(keyword)
.build();

newsRepository.save(news);

}



// User 정보 검증
private User validateUser(UserPrincipal userPrincipal) {
Optional<User> userOptional = userService.findById(userPrincipal.getId());
DefaultAssert.isOptionalPresent(userOptional);
if (userOptional.isEmpty()) { throw new UserNotFoundException(); }
return userOptional.get();
}

// Keyword 정보 검증
private Keyword validateKeyword(Long keywordId) {
Optional<Keyword> keywordOptional = keywordRepository.findById(keywordId);
if (keywordOptional.isEmpty()) { throw new KeywordNotFoundException(); }
return keywordOptional.get();
}


}
38 changes: 38 additions & 0 deletions src/main/java/com/movelog/domain/news/domain/News.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.movelog.domain.news.domain;

import com.movelog.domain.common.BaseEntity;
import com.movelog.domain.record.domain.Keyword;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "News")
@NoArgsConstructor
@Getter
public class News extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "news_id", updatable = false)
private Long newsId;

private String headLine; //뉴스 헤드라인

private String newsUrl; //뉴스 URL

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "keyword_id")
private Keyword keyword;

@Builder
public News(String headLine, String newsUrl, Keyword keyword) {
this.headLine = headLine;
this.newsUrl = newsUrl;
this.keyword = keyword;
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.movelog.domain.news.domain.repository;

import com.movelog.domain.news.domain.News;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface NewsRepository extends JpaRepository<News, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.movelog.domain.news.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class CreateNewsReq {

@Schema( type = "String", example ="5년 만의 첫 도전, 무엇이 그를 움직이게 했나?", description="사용자가 선택한/생성한 헤드라인 정보입니다.")
private String headLine;

}
Original file line number Diff line number Diff line change
@@ -13,12 +13,4 @@
public class NewsHeadLineReq {
@Schema( type = "String", example ="첫 도전, 오랜만에 다시, 꾸준히 이어온 기록, 끊어낸 습관 중 택 1", description="뉴스 헤드라인 고정 옵션입니다.")
private String option;

@Schema( type = "String", example ="했어요, 먹었어요, 갔어요 중 택 1", description="사용자가 선택한 동사 정보입니다.")
private String verb;

@Schema( type = "String", example ="클라이밍", description="사용자가 선택한 명사 정보입니다.")
private String noun;


}
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package com.movelog.domain.news.presentation;

import com.movelog.domain.news.application.NewsService;
import com.movelog.domain.news.dto.request.CreateNewsReq;
import com.movelog.domain.news.dto.request.NewsHeadLineReq;
import com.movelog.domain.news.dto.response.HeadLineRes;
import com.movelog.global.config.security.token.CurrentUser;
import com.movelog.global.config.security.token.UserPrincipal;
import com.movelog.global.payload.Message;
import com.movelog.global.util.ApiResponseUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;

import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.ErrorResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@@ -30,17 +37,43 @@ public class NewsController {

@Operation(summary = "뉴스 헤드라인 생성 API", description = "뉴스 헤드라인을 생성하는 API입니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "뉴스 헤드라인 생성 성공"),
@ApiResponse(responseCode = "400", description = "뉴스 헤드라인 생성 실패")
@ApiResponse(responseCode = "200", description = "뉴스 헤드라인 생성 성공",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))),
@ApiResponse(responseCode = "400", description = "뉴스 헤드라인 생성 실패",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
})
@PostMapping("/headline")
public List<HeadLineRes> createHeadLine(
@Parameter(description = "Access Token을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal,
@PostMapping("/{keywordId}/headline")
public ResponseEntity<?> createHeadLine(
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserPrincipal userPrincipal,
@Parameter(description = "키워드 ID(동사-명사 쌍에 대한 ID)를 입력해주세요.", required = true) @PathVariable Long keywordId,
@Parameter(description = "뉴스 헤드라인 생성 요청", required = true) @RequestBody NewsHeadLineReq newsHeadLineReq
) {
return newsService.createHeadLine(userPrincipal, newsHeadLineReq);
List<HeadLineRes> response = newsService.createHeadLine(userPrincipal, keywordId, newsHeadLineReq);
return ResponseEntity.ok(ApiResponseUtil.success(response));
}


@Operation(summary = "뉴스 생성 및 저장 API(기존 이미지 기록 기반)", description = "사용자의 기존 기록 이미지로 뉴스를 생성합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "뉴스 생성 및 저장 성공",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = Message.class))),
@ApiResponse(responseCode = "400", description = "뉴스 생성 및 저장 실패",
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)))
})
@PostMapping("/{keywordId}")
public ResponseEntity<?> createNews(
@Parameter(description = "Access Token을 입력해주세요.", required = true) @AuthenticationPrincipal UserPrincipal userPrincipal,
@Parameter(description = "키워드 ID(동사-명사 쌍에 대한 ID)를 입력해주세요.", required = true) @PathVariable Long keywordId,
@Parameter(description = "뉴스 생성 및 저장을 위한 정보를 입력해주세요", required = true) @RequestPart CreateNewsReq createNewsReq,
@Parameter(description = "뉴스 이미지를 파일 형식으로 입력해주세요", required = true) @RequestParam(value = "img", required = false) MultipartFile img
) {
newsService.createNews(userPrincipal, keywordId, createNewsReq, img);
return ResponseEntity.ok(ApiResponseUtil.success(Message.builder().message("뉴스가 생성되었습니다.").build()));
}






}
19 changes: 17 additions & 2 deletions src/main/java/com/movelog/domain/record/domain/Keyword.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.movelog.domain.record.domain;

import com.movelog.domain.common.BaseEntity;
import com.movelog.domain.news.domain.News;
import com.movelog.domain.user.domain.User;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
@@ -20,13 +22,26 @@ public class Keyword extends BaseEntity {
@Column(name = "keyword_id", updatable = false)
private Long keywordId;

private String keyword;
private String keyword; //명사

@Enumerated(EnumType.STRING) // Enum을 문자열로 저장
@Column(name = "verb_type")
private VerbType verbType;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "keyword")
private List<Record> records = new ArrayList<>();

@OneToMany(mappedBy = "keyword")
private List<News> news = new ArrayList<>();

@Builder
public Keyword(String keyword) {
public Keyword(User user, String keyword, VerbType verbType) {
this.user = user;
this.keyword = keyword;
this.verbType = verbType;
}
}
11 changes: 1 addition & 10 deletions src/main/java/com/movelog/domain/record/domain/Record.java
Original file line number Diff line number Diff line change
@@ -20,28 +20,19 @@ public class Record extends BaseEntity {
@Column(name = "record_id", updatable = false)
private Long recordId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "keyword_id")
private Keyword keyword;

@Enumerated(EnumType.STRING) // Enum을 문자열로 저장
private VerbType verbType;

@Column(name = "record_image")
private String recordImage;

@Column(name = "action_time")
private java.time.LocalDateTime actionTime;

@Builder
public Record(User user, Keyword keyword, VerbType verbType, String recordImage) {
this.user = user;
public Record(Keyword keyword, String recordImage) {
this.keyword = keyword;
this.verbType = verbType;
this.recordImage = recordImage;
this.actionTime = actionTime == null? LocalDateTime.now():actionTime;
}
5 changes: 5 additions & 0 deletions src/main/java/com/movelog/domain/record/domain/VerbType.java
Original file line number Diff line number Diff line change
@@ -22,4 +22,9 @@ public static VerbType fromValue(String value) {
}
throw new IllegalArgumentException("No enum constant for value: " + value);
}

public static String getStringVerbType(VerbType verbType) {
return verbType.getVerbType();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.movelog.domain.record.exception;


import com.movelog.global.exception.NotFoundException;

public class KeywordNotFoundException extends NotFoundException {

public KeywordNotFoundException() {
super("U002", "키워드를 찾을 수 없습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ public ResponseEntity<ApiResponse> retrieveTodayRecord(

ApiResponse result = ApiResponse.builder()
.check(true)
.information(recordService.retrieveTodayRecord(userPrincipal.getId()))
.information(recordService.retrieveTodayRecord(5L))
.build();
return ResponseEntity.ok(result);
}
Original file line number Diff line number Diff line change
@@ -2,9 +2,13 @@

import com.movelog.domain.record.domain.Keyword;
import com.movelog.domain.record.domain.Record;
import com.movelog.domain.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface KeywordRepository extends JpaRepository<Keyword,Long> {
List<Keyword> findByUser(User user);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.movelog.domain.record.repository;

import com.movelog.domain.record.domain.Keyword;
import com.movelog.domain.record.domain.Record;
import com.movelog.domain.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -10,5 +11,5 @@

@Repository
public interface RecordRepository extends JpaRepository<Record,Long> {
List<Record> findByUserAndActionTimeBetween(User user, LocalDateTime startOfDay, LocalDateTime endOfDay);
List<Record> findByKeywordInAndActionTimeBetween(List<Keyword> keywords, LocalDateTime startTime, LocalDateTime endTime);
}
63 changes: 41 additions & 22 deletions src/main/java/com/movelog/domain/record/service/RecordService.java
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
import com.movelog.domain.record.repository.RecordRepository;
import com.movelog.domain.user.domain.User;
import com.movelog.domain.user.domain.repository.UserRepository;
import com.movelog.global.DefaultAssert;
import com.movelog.global.util.S3Util;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -19,8 +18,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

@Service
@@ -36,22 +34,24 @@ public class RecordService {
@Transactional
public void createRecord(Long userId, CreateRecordReq createRecordReq, MultipartFile img) {
User user = validUserById(userId);
String recordImgUrl = s3Util.upload(img);
// User user = validUserById(5L);
String recordImgUrl = s3Util.uploadToRecordFolder(img);
log.info("recordImgUrl: {}", recordImgUrl);

Keyword keyword = Keyword.builder()
.keyword(createRecordReq.getNoun())
.build();

keywordRepository.save(keyword);
String verb = createRecordReq.getVerbType();
try {
VerbType verbType = VerbType.fromValue(verb);

Record record = Record.builder()
Keyword keyword = Keyword.builder()
.user(user)
.keyword(keyword)
.keyword(createRecordReq.getNoun())
.verbType(verbType)
.build();

keywordRepository.save(keyword);

Record record = Record.builder()
.keyword(keyword)
.recordImage(recordImgUrl)
// .actionTime(LocalDateTime.now())
.build();
@@ -62,26 +62,45 @@ public void createRecord(Long userId, CreateRecordReq createRecordReq, Multipart
}

}

private User validUserById(Long userId) {
Optional<User> userOptional = userRepository.findById(userId);
return userOptional.get();
}

public List<VerbType> retrieveTodayRecord(Long userId) {
public Map<String, Boolean> retrieveTodayRecord(Long userId) {
// 유저 유효성 검사 및 조회
User user = validUserById(userId);
// 현재 날짜 가져오기
LocalDate today = LocalDate.now(); // 오늘 날짜 (2025-01-05 기준)

// 오늘의 시작 시간과 끝 시간 계산
LocalDateTime startOfDay = today.atStartOfDay(); // 2025-01-05T00:00:00
LocalDateTime endOfDay = today.atTime(LocalTime.MAX); // 2025-01-05T23:59:59.999999999
LocalDate today = LocalDate.now();
LocalDateTime startOfDay = today.atStartOfDay();
LocalDateTime endOfDay = today.atTime(LocalTime.MAX);

// 유저가 소유한 키워드 가져오기
List<Keyword> keywords = keywordRepository.findByUser(user);

// 키워드에 연결된 기록 중 오늘 생성된 기록 가져오기
List<Record> records = recordRepository.findByKeywordInAndActionTimeBetween(keywords, startOfDay, endOfDay);

log.info("Retrieved Records: {}", records);

// 레코드 조회
List<Record> records = recordRepository.findByUserAndActionTimeBetween(user, startOfDay, endOfDay);
// Keyword에서 VerbType 추출
Set<VerbType> todayVerbTypes = records.stream()
.map(Record::getKeyword) // Record -> Keyword
.map(Keyword::getVerbType) // Keyword -> VerbType
.collect(Collectors.toSet()); // 중복 제거

return records.stream()
.map(Record::getVerbType) // Record 객체에서 verbType 추출
.distinct() // 중복 제거
.collect(Collectors.toList());
log.info("Today VerbTypes: {}", todayVerbTypes);

// 모든 VerbType에 대해 존재 여부를 반환
return Arrays.stream(VerbType.values())
.collect(Collectors.toMap(
VerbType::getVerbType, // 키: VerbType의 문자열 값
todayVerbTypes::contains // 값: 오늘 VerbType에 포함 여부
));
}



}
3 changes: 2 additions & 1 deletion src/main/java/com/movelog/domain/user/domain/User.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@

import com.movelog.domain.common.BaseEntity;

import com.movelog.domain.record.domain.Keyword;
import com.movelog.domain.record.domain.Record;
import jakarta.persistence.*;
import lombok.AccessLevel;
@@ -40,7 +41,7 @@ public class User extends BaseEntity {
private String fcmToken;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Record> records = new ArrayList<>();
private List<Keyword> keywords = new ArrayList<>();


@Builder

This file was deleted.

23 changes: 14 additions & 9 deletions src/main/java/com/movelog/global/payload/ApiResponse.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package com.movelog.global.payload;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;

@Data
public class ApiResponse {

@Schema( type = "boolean", example = "true", description="올바르게 로직을 처리했으면 True, 아니면 False를 반환합니다.")
private boolean check;
public class ApiResponse<T> {

@Schema( type = "object", example = "information", description="restful의 정보를 감싸 표현합니다. object형식으로 표현합니다.")
private Object information;
@Schema(type = "boolean", example = "true", description = "로직 처리 성공 여부를 반환합니다.")
private final boolean check;

public ApiResponse(){};
@Schema(type = "object", description = "응답 데이터를 담는 필드입니다.")
private final T information;

@Builder
public ApiResponse(boolean check, Object information) {
public ApiResponse(boolean check, T information) {
this.check = check;
this.information = information;
}

// 정적 팩토리 메서드로 명확한 응답 생성
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(true, data);
}

public static <T> ApiResponse<T> failure(T errorMessage) {
return new ApiResponse<>(false, errorMessage);
}
}
31 changes: 31 additions & 0 deletions src/main/java/com/movelog/global/util/ApiResponseUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.movelog.global.util;

import com.movelog.global.payload.ApiResponse;
import com.movelog.global.payload.ErrorResponse;
import lombok.experimental.UtilityClass;
import org.springframework.http.ResponseEntity;

import java.util.List;
@UtilityClass
public class ApiResponseUtil {

public static <T> ResponseEntity<ApiResponse<T>> success(T data) {
ApiResponse<T> apiResponse = ApiResponse.<T>builder()
.check(true)
.information(data)
.build();

return ResponseEntity.ok(apiResponse);
}

public static <T> ResponseEntity<ApiResponse<List<T>>> success(List<T> data) {
ApiResponse<List<T>> apiResponse = ApiResponse.<List<T>>builder()
.check(true)
.information(data)
.build();

return ResponseEntity.ok(apiResponse);
}


}
22 changes: 22 additions & 0 deletions src/main/java/com/movelog/global/util/ErrorResponseUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.movelog.global.util;

import com.movelog.global.payload.ErrorResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

public class ErrorResponseUtil {

public static ResponseEntity<ErrorResponse> failure(
String errorCode, HttpStatus status, String message, Class<?> clazz) {
ErrorResponse errorResponse = ErrorResponse.builder()
.code(errorCode)
.status(status.value())
.message(message)
.clazz(clazz.getSimpleName())
.build();

return ResponseEntity.status(status).body(errorResponse);
}

}

24 changes: 19 additions & 5 deletions src/main/java/com/movelog/global/util/S3Util.java
Original file line number Diff line number Diff line change
@@ -48,23 +48,37 @@ public AmazonS3Client amazonS3Client() {
.build();
}

public String upload(MultipartFile file) {

public String uploadToRecordFolder(MultipartFile file) {
return uploadToFolder(file, "record");
}

public String uploadToNewsFolder(MultipartFile file) {
return uploadToFolder(file, "news");
}

private String uploadToFolder(MultipartFile file, String folder) {
if (!folder.endsWith("/")) {
folder += "/";
}
return upload(file, folder + createFileName(file.getOriginalFilename()));
}

private String upload(MultipartFile file, String filePath) {
String imageUrl = "";
String fileName = createFileName(file.getOriginalFilename());
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(file.getSize());
objectMetadata.setContentType(file.getContentType());

try (InputStream inputStream = file.getInputStream()) {
s3Client.putObject(new PutObjectRequest(bucket, fileName, inputStream, objectMetadata)
s3Client.putObject(new PutObjectRequest(bucket, filePath, inputStream, objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
imageUrl = s3Client.getUrl(bucket, fileName).toString();
imageUrl = s3Client.getUrl(bucket, filePath).toString();
} catch (IOException e) {
throw new IllegalArgumentException("IMAGE_UPLOAD_ERROR");
}
return imageUrl;
}

// 이미지파일명 중복 방지
private String createFileName(String fileName) {
return UUID.randomUUID().toString().concat(getFileExtension(fileName));

0 comments on commit cc46fdd

Please sign in to comment.