diff --git a/src/main/java/com/weatherfit/board/service/BoardService.java b/src/main/java/com/weatherfit/board/service/BoardService.java index 2c1c468..5cbf97f 100644 --- a/src/main/java/com/weatherfit/board/service/BoardService.java +++ b/src/main/java/com/weatherfit/board/service/BoardService.java @@ -157,12 +157,6 @@ public void patchBoard(int boardId, String boardJson, MultipartFile[] images, St ObjectMapper objectMapper = new ObjectMapper(); - // 기존 이미지 삭제 - for (ImageEntity image : originalBoard.getImages()) { - imageService.deleteImage(image.getImage_url()); - imageRepository.delete(image); - } - BoardUpdateDTO boardUpdateDTO; try { boardUpdateDTO = objectMapper.readValue(boardJson, BoardUpdateDTO.class); @@ -171,25 +165,40 @@ public void patchBoard(int boardId, String boardJson, MultipartFile[] images, St } catch (JsonProcessingException e) { throw new RuntimeException(e); } - BoardEntity boardEntity = BoardEntity.builder() - .boardId(boardId) - .content(boardUpdateDTO.getContent()) - .category(boardUpdateDTO.getCategory()) - .hashTag(boardUpdateDTO.getHashTag()) - .build(); - BoardEntity savedBoard = boardRepository.save(boardEntity); + List newImages = new ArrayList<>(); for (MultipartFile image : images) { String imageUrl = imageService.saveImage(image); ImageEntity imageEntity = ImageEntity.builder() .image_url(imageUrl) - .boardId(originalBoard) // savedBoard를 originalBoard로 변경 + .boardId(originalBoard) .build(); imageRepository.save(imageEntity); + + newImages.add(imageEntity); + } + + // 새로운 이미지 URL과 기존의 이미지 URL을 비교하여 이미지가 수정되었는지 판단합니다. + for (ImageEntity originalImage : originalBoard.getImages()) { + boolean isModified = newImages.stream().noneMatch(newImage -> newImage.getImage_url().equals(originalImage.getImage_url())); + if (isModified) { + // 이미지가 수정되었을 경우, 기존의 이미지를 삭제합니다. + imageService.deleteImage(originalImage.getImage_url()); + imageRepository.delete(originalImage); + } } + BoardEntity boardEntity = BoardEntity.builder() + .boardId(boardId) + .content(boardUpdateDTO.getContent()) + .category(boardUpdateDTO.getCategory()) + .hashTag(boardUpdateDTO.getHashTag()) + .images(newImages) + .build(); + + BoardEntity savedBoard = boardRepository.save(boardEntity); String afterJoiendString = originalBoard.getTemperature() + "/" + String.join("/", originalBoard.getCategory()) + ":" + String.join("/", boardUpdateDTO.getCategory()); String afterJoiendString2 = String.join("/", originalBoard.getHashTag()) + ":" + String.join("/", boardUpdateDTO.getHashTag()); @@ -198,16 +207,15 @@ public void patchBoard(int boardId, String boardJson, MultipartFile[] images, St originalBoard.setContent(boardUpdateDTO.getContent()); originalBoard.setCategory(boardUpdateDTO.getCategory()); originalBoard.setHashTag(boardUpdateDTO.getHashTag()); - originalBoard.setImages(boardUpdateDTO.getImages()); // 이미지 정보를 boardUpdateDTO에서 가져오는 것이 아니라, 위에서 새로 추가한 이미지 정보를 사용해야 합니다. + originalBoard.setImages(newImages); boardRepository.save(originalBoard); - // 카프카 전송 kafkaTemplate.send("category", 1, "category", afterJoiendString); kafkaTemplate.send("hashtag", 1, "hashtag", afterJoiendString2); - } + // 게시글 삭제 public void deleteBoard(int boardId) { Optional optionalBoard = Optional.ofNullable(boardRepository.findById(boardId)); diff --git a/src/main/java/com/weatherfit/board/service/ImageService.java b/src/main/java/com/weatherfit/board/service/ImageService.java index 98e0275..7e8c5ec 100644 --- a/src/main/java/com/weatherfit/board/service/ImageService.java +++ b/src/main/java/com/weatherfit/board/service/ImageService.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.math.BigInteger; +import java.security.MessageDigest; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.UUID; @@ -27,22 +29,28 @@ public class ImageService { public String saveImage(MultipartFile file) { try { - String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); String originalFilename = file.getOriginalFilename(); - String fileName = timestamp + "_" + originalFilename; + String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".")); + + // 이미지의 해시값을 생성합니다. + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] imageBytes = file.getBytes(); + byte[] digest = md.digest(imageBytes); + String imageHash = new BigInteger(1, digest).toString(16); // 변경된 부분 + + // 이미지 이름에 해시값을 사용합니다. + String fileName = imageHash + fileExtension; String fileUrl = "https://" + bucketName + ".s3.amazonaws.com/" + fileName; - if (amazonS3Client.doesObjectExist(bucketName, fileName)) { - fileName = timestamp + "_" + UUID.randomUUID().toString() + "_" + originalFilename; - fileUrl = "https://" + bucketName + ".s3.amazonaws.com/" + fileName; + if (!amazonS3Client.doesObjectExist(bucketName, fileName)) { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(file.getContentType()); + metadata.setContentLength(file.getSize()); + amazonS3Client.putObject(bucketName, fileName, file.getInputStream(), metadata); } - ObjectMetadata metadata = new ObjectMetadata(); - metadata.setContentType(file.getContentType()); - metadata.setContentLength(file.getSize()); - amazonS3Client.putObject(bucketName, fileName, file.getInputStream(), metadata); return fileUrl; - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Failed to upload image to S3", e); }