diff --git a/src/main/java/modernfarmer/server/farmususer/global/config/s3/AmazonS3ResourceStorage.java b/src/main/java/modernfarmer/server/farmususer/global/config/s3/AmazonS3ResourceStorage.java deleted file mode 100644 index 402cb8c..0000000 --- a/src/main/java/modernfarmer/server/farmususer/global/config/s3/AmazonS3ResourceStorage.java +++ /dev/null @@ -1,34 +0,0 @@ -package modernfarmer.server.farmususer.global.config.s3; - -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.CannedAccessControlList; -import com.amazonaws.services.s3.model.PutObjectRequest; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; - -@Component -@RequiredArgsConstructor -public class AmazonS3ResourceStorage { - @Value("${cloud.aws.s3.bucket}") - private String bucket; - private final AmazonS3Client amazonS3Client; - - public void store(String fullPath, MultipartFile multipartFile) { - File file = new File(MultipartUtil.getLocalHomeDirectory(), fullPath); - try { - multipartFile.transferTo(file); - amazonS3Client.putObject(new PutObjectRequest(bucket, fullPath, file) - .withCannedAcl(CannedAccessControlList.PublicRead)); - } catch (Exception e) { - throw new RuntimeException(); - } finally { - if (file.exists()) { - file.delete(); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/modernfarmer/server/farmususer/global/config/s3/FileDetail.java b/src/main/java/modernfarmer/server/farmususer/global/config/s3/FileDetail.java deleted file mode 100644 index f777dfd..0000000 --- a/src/main/java/modernfarmer/server/farmususer/global/config/s3/FileDetail.java +++ /dev/null @@ -1,34 +0,0 @@ -package modernfarmer.server.farmususer.global.config.s3; - -import lombok.*; -import org.springframework.web.multipart.MultipartFile; - -import java.time.LocalDateTime; - -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor(access = AccessLevel.PROTECTED) -@Builder -public class FileDetail { - private String id; - private String name; - private String format; - private String path; - private long bytes; - - @Builder.Default - private LocalDateTime createdAt = LocalDateTime.now(); - - public static FileDetail multipartOf(MultipartFile multipartFile) { - final String fileId = MultipartUtil.createFileId(); - final String format = MultipartUtil.getFormat(multipartFile.getContentType()); - return FileDetail.builder() - .id(fileId) - .name(multipartFile.getOriginalFilename()) - .format(format) - .path(MultipartUtil.createPath(fileId, format)) - .bytes(multipartFile.getSize()) - .build(); - } -} \ No newline at end of file diff --git a/src/main/java/modernfarmer/server/farmususer/global/config/s3/MultipartUtil.java b/src/main/java/modernfarmer/server/farmususer/global/config/s3/MultipartUtil.java deleted file mode 100644 index f60f54b..0000000 --- a/src/main/java/modernfarmer/server/farmususer/global/config/s3/MultipartUtil.java +++ /dev/null @@ -1,45 +0,0 @@ -package modernfarmer.server.farmususer.global.config.s3; - -import org.springframework.util.StringUtils; - -import java.util.UUID; - -public final class MultipartUtil { - private static final String BASE_DIR = "images"; - - /** - * 로컬에서의 사용자 홈 디렉토리 경로를 반환합니다. - */ - public static String getLocalHomeDirectory() { - return System.getProperty("user.home"); - } - - /** - * 새로운 파일 고유 ID를 생성합니다. - * @return 36자리의 UUID - */ - public static String createFileId() { - return UUID.randomUUID().toString(); - } - - /** - * Multipart 의 ContentType 값에서 / 이후 확장자만 잘라냅니다. - * @param contentType ex) image/png - * @return ex) png - */ - public static String getFormat(String contentType) { - if (StringUtils.hasText(contentType)) { - return contentType.substring(contentType.lastIndexOf('/') + 1); - } - return null; - } - - /** - * 파일의 전체 경로를 생성합니다. - * @param fileId 생성된 파일 고유 ID - * @param format 확장자 - */ - public static String createPath(String fileId, String format) { - return String.format("%s/%s.%s", BASE_DIR, fileId, format); - } -} \ No newline at end of file diff --git a/src/main/java/modernfarmer/server/farmususer/global/config/s3/S3Uploader.java b/src/main/java/modernfarmer/server/farmususer/global/config/s3/S3Uploader.java new file mode 100644 index 0000000..f020922 --- /dev/null +++ b/src/main/java/modernfarmer/server/farmususer/global/config/s3/S3Uploader.java @@ -0,0 +1,68 @@ +package modernfarmer.server.farmususer.global.config.s3; + +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.PutObjectRequest; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Optional; +import java.util.UUID; + +@Slf4j +@Component +public class S3Uploader { + private final AmazonS3Client amazonS3Client; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + public S3Uploader(AmazonS3Client amazonS3Client) { + this.amazonS3Client = amazonS3Client; + } + + public String uploadFiles( + MultipartFile multipartFile, String dirName) throws IOException { + File uploadFile = convert(multipartFile).orElseThrow(() -> + new IllegalArgumentException("error: MultipartFile -> File convert fail")); + return upload(uploadFile, dirName); + } + + public String upload(File uploadFile, String filePath) { + String fileName = filePath + "/" + UUID.randomUUID() + uploadFile.getName(); + String uploadImageUrl = putS3(uploadFile, fileName); + removeNewFile(uploadFile); + return uploadImageUrl; + } + + private String putS3(File uploadFile, String fileName) { + amazonS3Client.putObject( + new PutObjectRequest(bucket, fileName, uploadFile) + .withCannedAcl(CannedAccessControlList.PublicRead)); + return amazonS3Client.getUrl(bucket, fileName).toString(); + } + + private void removeNewFile(File targetFile) { + if (targetFile.delete()) { + System.out.println("File delete success"); + return; + } + System.out.println("File delete fail"); + } + + private Optional convert(MultipartFile file) throws IOException { + File convertFile = new File(System.getProperty("user.dir") + "/" + file.getOriginalFilename()); + if (convertFile.createNewFile()) { + try (FileOutputStream fileOutputStream = new FileOutputStream(convertFile)) { + fileOutputStream.write(file.getBytes()); + } + return Optional.of(convertFile); + } + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/main/java/modernfarmer/server/farmususer/user/controller/UserController.java b/src/main/java/modernfarmer/server/farmususer/user/controller/UserController.java index c24faee..f5587cf 100644 --- a/src/main/java/modernfarmer/server/farmususer/user/controller/UserController.java +++ b/src/main/java/modernfarmer/server/farmususer/user/controller/UserController.java @@ -14,6 +14,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; +import java.io.IOException; @Slf4j @RestController @@ -24,12 +25,12 @@ public class UserController { private final UserService userService; private final JwtTokenProvider jwtTokenProvider; - @PostMapping(value = "/profileImage", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}) - public ResponseDto produceProfileImage(HttpServletRequest request, @RequestPart("file") MultipartFile multipartFile){ + @PostMapping(value = "/profileImage", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseDto produceProfileImage(HttpServletRequest request, @RequestPart("file") MultipartFile multipartFile) throws IOException { String userId = jwtTokenProvider.getUserId(request); - - ResponseDto responseDto = userService.produceProfileImage(Long.valueOf(userId), multipartFile); + log.info(userId); + ResponseDto responseDto = userService.emitProfileImage(Long.valueOf(userId), multipartFile); return responseDto; @@ -40,6 +41,7 @@ public ProfileImageResponseDto selectProfileImage(HttpServletRequest request){ String userId = jwtTokenProvider.getUserId(request); + ProfileImageResponseDto profileImageResponseDto = userService.selectProfileImage(Long.valueOf(userId)); return profileImageResponseDto; @@ -59,21 +61,11 @@ public ResponseDto deleteUser(HttpServletRequest request){ @PostMapping(value = "/nickname") - public ResponseDto produceNickname(HttpServletRequest request, @RequestBody ProduceNicknameRequest produceNicknameRequest){ - - String userId = jwtTokenProvider.getUserId(request); - - ResponseDto responseDto = userService.produceNickname(Long.valueOf(userId), produceNicknameRequest.getNickName()); - - return responseDto; - } - - @PatchMapping(value = "/nickname") - public ResponseDto updateNickname(HttpServletRequest request, @RequestBody ProduceNicknameRequest produceNicknameRequest){ + public ResponseDto emitNickname(HttpServletRequest request, @RequestBody ProduceNicknameRequest produceNicknameRequest){ String userId = jwtTokenProvider.getUserId(request); - ResponseDto responseDto = userService.produceNickname(Long.valueOf(userId), produceNicknameRequest.getNickName()); + ResponseDto responseDto = userService.emitNickname(Long.valueOf(userId), produceNicknameRequest.getNickName()); return responseDto; } diff --git a/src/main/java/modernfarmer/server/farmususer/user/dto/response/ResponseDto.java b/src/main/java/modernfarmer/server/farmususer/user/dto/response/ResponseDto.java index c78237c..d4169cb 100644 --- a/src/main/java/modernfarmer/server/farmususer/user/dto/response/ResponseDto.java +++ b/src/main/java/modernfarmer/server/farmususer/user/dto/response/ResponseDto.java @@ -7,6 +7,7 @@ @NoArgsConstructor @AllArgsConstructor @SuperBuilder +@Getter public class ResponseDto { private int code; private String message; diff --git a/src/main/java/modernfarmer/server/farmususer/user/repository/UserRepository.java b/src/main/java/modernfarmer/server/farmususer/user/repository/UserRepository.java index 5dec76e..33c6fc2 100644 --- a/src/main/java/modernfarmer/server/farmususer/user/repository/UserRepository.java +++ b/src/main/java/modernfarmer/server/farmususer/user/repository/UserRepository.java @@ -3,6 +3,7 @@ import io.lettuce.core.dynamic.annotation.Param; import modernfarmer.server.farmususer.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -11,20 +12,22 @@ @Repository public interface UserRepository extends JpaRepository { - - Optional findByUsernumber(String usernumber); @Query("SELECT a.role FROM User AS a WHERE a.id = :userId") String findUserRole(@Param("userId") Long userId); - @Query("update User as u set u = :nickName where u.id = :userId") + @Modifying + @Query("update User as u set u.nickname = :nickName where u.id = :userId") void updateUserNickname(@Param("nickName") String nickName, @Param("userId") Long userId); - - @Query("delete from User as u where u.id = : userId") + @Modifying + @Query("delete from User as u where u.id = :userId") void deleteUser(@Param("userId") Long userId); @Query("select u.profileImage from User as u where u.id = :userId") String selectUserProfileImage(@Param("userId") Long userId); + @Modifying + @Query("update User as u set u.profileImage = :profileImage where u.id = :userId") + void emitUserProfileImage(@Param("userId") Long userId, @Param("profileImage") String profileImage); diff --git a/src/main/java/modernfarmer/server/farmususer/user/service/AuthService.java b/src/main/java/modernfarmer/server/farmususer/user/service/AuthService.java index 1b73a5c..9978c2a 100644 --- a/src/main/java/modernfarmer/server/farmususer/user/service/AuthService.java +++ b/src/main/java/modernfarmer/server/farmususer/user/service/AuthService.java @@ -28,7 +28,7 @@ public class AuthService{ public UserRepository userRepository; private final WebClient webClient; - private boolean early = false; + @Autowired public AuthService(WebClient webClient, UserRepository userRepository, JwtTokenProvider jwtTokenProvider, RedisTemplate redisTemplate) { @@ -41,6 +41,7 @@ public AuthService(WebClient webClient, UserRepository userRepository, JwtTokenP public TokenResponseDto googleLogin(String accessToken) { User user; + boolean early = false; Mono userInfoMono = getUserGoogleInfo(accessToken); GoogleUserResponseDto userInfo = userInfoMono.block(); @@ -88,6 +89,7 @@ public TokenResponseDto googleLogin(String accessToken) { public TokenResponseDto kakaoLogin(String accessToken) { User user; + boolean early = false; Mono userInfoMono = getUserKakaoInfo(accessToken); KakaoUserResponseDto userInfo = userInfoMono.block(); diff --git a/src/main/java/modernfarmer/server/farmususer/user/service/UserService.java b/src/main/java/modernfarmer/server/farmususer/user/service/UserService.java index 0def733..6cec29c 100644 --- a/src/main/java/modernfarmer/server/farmususer/user/service/UserService.java +++ b/src/main/java/modernfarmer/server/farmususer/user/service/UserService.java @@ -1,8 +1,7 @@ package modernfarmer.server.farmususer.user.service; import lombok.extern.slf4j.Slf4j; -import modernfarmer.server.farmususer.global.config.s3.AmazonS3ResourceStorage; -import modernfarmer.server.farmususer.global.config.s3.FileDetail; +import modernfarmer.server.farmususer.global.config.s3.S3Uploader; import modernfarmer.server.farmususer.global.exception.notfound.NotFoundRefreshTokenException; import modernfarmer.server.farmususer.user.dto.response.ProfileImageResponseDto; import modernfarmer.server.farmususer.user.dto.response.ResponseDto; @@ -10,12 +9,14 @@ import modernfarmer.server.farmususer.user.repository.UserRepository; import modernfarmer.server.farmususer.user.util.JwtTokenProvider; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.reactive.function.client.WebClient; +import java.io.IOException; + @Slf4j @Service @@ -24,26 +25,27 @@ public class UserService { public JwtTokenProvider jwtTokenProvider; public RedisTemplate redisTemplate; public UserRepository userRepository; - private final AmazonS3ResourceStorage amazonS3ResourceStorage; + public final S3Uploader s3Uploader; + @Autowired - public UserService(WebClient webClient, UserRepository userRepository, JwtTokenProvider jwtTokenProvider, RedisTemplate redisTemplate, AmazonS3ResourceStorage amazonS3ResourceStoraget) { + public UserService(UserRepository userRepository, JwtTokenProvider jwtTokenProvider, RedisTemplate redisTemplate, + S3Uploader s3Uploader + ) { this.userRepository = userRepository; this.jwtTokenProvider = jwtTokenProvider; this.redisTemplate = redisTemplate; - this.amazonS3ResourceStorage = amazonS3ResourceStoraget; - } - + this.s3Uploader = s3Uploader; - public ResponseDto produceProfileImage(Long userId, MultipartFile multipartFile){ - - - FileDetail fileDetail = FileDetail.multipartOf(multipartFile); - amazonS3ResourceStorage.store(fileDetail.getPath(), multipartFile); + } + @Transactional + public ResponseDto emitProfileImage(Long userId, MultipartFile multipartFile) throws IOException { - log.info(String.valueOf(fileDetail)); + String imageUrl = s3Uploader.uploadFiles(multipartFile, "userprofileimage"); + log.info(imageUrl); + userRepository.emitUserProfileImage(userId, imageUrl); ResponseDto responseDto = ResponseDto .builder() @@ -70,12 +72,7 @@ public ProfileImageResponseDto selectProfileImage(Long userId){ return profileImageResponseDto; } - - - - - - + @Transactional public ResponseDto deleteUser(Long userId){ userRepository.deleteUser(userId); @@ -90,7 +87,8 @@ public ResponseDto deleteUser(Long userId){ } - public ResponseDto produceNickname(Long userId, String nickName){ + @Transactional + public ResponseDto emitNickname(Long userId, String nickName){ userRepository.updateUserNickname(nickName, userId);