Skip to content

Commit

Permalink
Merge pull request #79 from AR-TTUBEOG/feature/76-2
Browse files Browse the repository at this point in the history
[Feature] 이미지 멀티파트폼 구현
  • Loading branch information
choeun7 authored Feb 18, 2024
2 parents bfe6d2e + d654ed6 commit c31e179
Show file tree
Hide file tree
Showing 23 changed files with 576 additions and 254 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ dependencies {
runtimeOnly("io.netty:netty-resolver-dns-native-macos:4.1.94.Final:osx-aarch_64")
}

implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

}


Expand Down
40 changes: 40 additions & 0 deletions src/main/java/com/ttubeog/domain/UuidImage/domain/UuidImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ttubeog.domain.UuidImage.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Getter
@Builder
@Table(name = "uuid_image")
public class UuidImage {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(unique = true)
private String uuid;

@Column(name = "image_url")
private String imageUrl;

public UuidImage(Long id, String uuid, String imageUrl) {
this.id = id;
this.uuid = uuid;
this.imageUrl = imageUrl;
}

public void updateImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ttubeog.domain.UuidImage.domain.repository;

import com.ttubeog.domain.UuidImage.domain.UuidImage;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UuidImageRepository extends JpaRepository<UuidImage, Long> {
}
48 changes: 48 additions & 0 deletions src/main/java/com/ttubeog/domain/aws/s3/AmazonS3Manager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.ttubeog.domain.aws.s3;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.ttubeog.domain.UuidImage.domain.UuidImage;
import com.ttubeog.domain.image.domain.Image;
import com.ttubeog.global.config.AmazonConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Slf4j
@Component
@RequiredArgsConstructor
public class AmazonS3Manager {

private final AmazonS3 amazonS3;

private final AmazonConfig amazonConfig;

public String uploadFile(String keyName, MultipartFile file) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(new PutObjectRequest(amazonConfig.getBucket(), keyName, file.getInputStream(), metadata));
}catch (IOException e) {
log.error("error at AmazonS3Manager uploadFile : {}", (Object) e.getStackTrace());
}

return amazonS3.getUrl(amazonConfig.getBucket(), keyName).toString();
}

public String generateSpotKeyName(Image image) {
return amazonConfig.getSpotPath() + '/' + image.getUuid();
}

public String generateStoreKeyName(Image image) {
return amazonConfig.getStorePath() + '/' + image.getUuid();
}

public String generateGuestBookKeyName(Image image) {
return amazonConfig.getGuestBookPath() + '/' + image.getUuid();
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/ttubeog/domain/aws/s3/S3PhotoService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ttubeog.domain.aws.s3;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.S3ObjectResource;
import com.amazonaws.services.s3.model.S3Object;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Service
public class S3PhotoService {

private final AmazonS3 amazonS3;

public S3PhotoService(AmazonS3 amazonS3) {
this.amazonS3 = amazonS3;
}

public InputStream downloadPhotoFromS3(String bucketName, String key) throws IOException {
S3Object object = amazonS3.getObject(bucketName, key);

return new ByteArrayInputStream(object.getObjectContent().readAllBytes());
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package com.ttubeog.domain.guestbook.application;

import com.ttubeog.domain.UuidImage.domain.UuidImage;
import com.ttubeog.domain.UuidImage.domain.repository.UuidImageRepository;
import com.ttubeog.domain.auth.security.JwtTokenProvider;
import com.ttubeog.domain.aws.s3.AmazonS3Manager;
import com.ttubeog.domain.guestbook.domain.GuestBook;
import com.ttubeog.domain.guestbook.domain.GuestBookType;
import com.ttubeog.domain.guestbook.domain.repository.GuestBookRepository;
import com.ttubeog.domain.guestbook.dto.request.CreateGuestBookRequestDto;
import com.ttubeog.domain.guestbook.dto.request.UpdateGuestBookRequestDto;
import com.ttubeog.domain.guestbook.dto.response.GuestBookResponseDto;
import com.ttubeog.domain.guestbook.exception.InvalidGuestBookException;
import com.ttubeog.domain.guestbook.exception.InvalidGuestBookIdException;
import com.ttubeog.domain.image.application.ImageService;
import com.ttubeog.domain.image.domain.Image;
import com.ttubeog.domain.image.domain.ImageType;
import com.ttubeog.domain.image.domain.repository.ImageRepository;
import com.ttubeog.domain.image.dto.request.CreateImageRequestDto;
import com.ttubeog.domain.image.exception.InvalidImageException;
import com.ttubeog.domain.member.domain.Member;
import com.ttubeog.domain.member.domain.repository.MemberRepository;
import com.ttubeog.domain.member.exception.InvalidMemberException;
Expand All @@ -37,6 +34,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RequiredArgsConstructor
@Service
Expand All @@ -48,8 +46,11 @@ public class GuestBookService {
private final SpotRepository spotRepository;
private final StoreRepository storeRepository;
private final ImageRepository imageRepository;
private final UuidImageRepository uuidImageRepository;

private final ImageService imageService;
//private final ImageService imageService;

private final AmazonS3Manager amazonS3Manager;

private final JwtTokenProvider jwtTokenProvider;

Expand Down Expand Up @@ -133,14 +134,6 @@ public ResponseEntity<?> createGuestBook(HttpServletRequest request, CreateGuest
guestBookRepository.save(guestBook);


CreateImageRequestDto createImageRequestDto = CreateImageRequestDto.builder()
.image(createGuestBookRequestDto.getImage())
.imageType(ImageType.GUESTBOOK)
.placeId(guestBook.getId())
.build();
imageService.createImage(createImageRequestDto);


if (createGuestBookRequestDto.getGuestBookType().equals(GuestBookType.SPOT)) {
spot = spotRepository.findById(createGuestBookRequestDto.getSpotId()).orElseThrow(InvalidSpotIdException::new);

Expand Down Expand Up @@ -176,25 +169,13 @@ public ResponseEntity<?> createGuestBook(HttpServletRequest request, CreateGuest
return getResponseEntity(guestBook);
}


// GuestBook 을 Id(PK) 값으로 찾는 Method 입니다. 현재 사용하지 않습니다.
public ResponseEntity<?> findByGuestBookId(HttpServletRequest request, Long guestBookId) {
Long memberId = jwtTokenProvider.getMemberId(request);

memberRepository.findById(memberId).orElseThrow(InvalidMemberException::new);

GuestBook guestBook = guestBookRepository.findById(guestBookId).orElseThrow(InvalidGuestBookIdException::new);

return getResponseEntity(guestBook);
}

// Spot ID 로 GuestBook 을 조회하는 Method 입니다.
public ResponseEntity<?> findGuestBookBySpotId(HttpServletRequest request, Long spotId, Integer pageNum) {
Long memberId = jwtTokenProvider.getMemberId(request);

memberRepository.findById(memberId).orElseThrow(InvalidMemberException::new);

Spot spot = spotRepository.findById(spotId).orElseThrow(InvalidSpotIdException::new);
Spot spot = spotRepository.findById(spotId).orElseThrow(InvalidStoreIdException::new);

Page<GuestBook> guestBookPage = guestBookRepository.findAllBySpot(spot, PageRequest.of(pageNum, 10));

Expand All @@ -218,6 +199,7 @@ public ResponseEntity<?> findGuestBookBySpotId(HttpServletRequest request, Long
return ResponseEntity.ok(apiResponse);
}


// Store ID 로 GuestBook 을 조회하는 Method 입니다.
public ResponseEntity<?> findGuestBookByStoreId(HttpServletRequest request, Long storeId, Integer pageNum) {
Long memberId = jwtTokenProvider.getMemberId(request);
Expand Down Expand Up @@ -249,35 +231,6 @@ public ResponseEntity<?> findGuestBookByStoreId(HttpServletRequest request, Long
}


// GuestBook 을 Update 하는 Method 입니다. 현재 따로 사용하지 않습니다.
@Transactional
public ResponseEntity<?> updateGuestBook(HttpServletRequest request, Long guestBookId, UpdateGuestBookRequestDto updateGuestBookRequestDto) {

Long memberId = jwtTokenProvider.getMemberId(request);

memberRepository.findById(memberId).orElseThrow(InvalidMemberException::new);

GuestBook guestBook = guestBookRepository.findById(guestBookId).orElseThrow(InvalidGuestBookIdException::new);

Image image = imageRepository.findByGuestBookId(guestBook.getId()).orElseThrow(InvalidImageException::new);

imageService.deleteImage(image.getId());

CreateImageRequestDto createImageRequestDto = CreateImageRequestDto.builder()
.image(updateGuestBookRequestDto.getImage())
.imageType(ImageType.GUESTBOOK)
.placeId(guestBookId)
.build();

Image newImage = imageRepository.findById(imageService.createImage(createImageRequestDto).getId()).orElseThrow(InvalidImageException::new);

guestBook.updateGuestBook(updateGuestBookRequestDto.getContent(), updateGuestBookRequestDto.getStar(), newImage);

guestBookRepository.save(guestBook);

return getResponseEntity(guestBook);
}

// GuestBook 을 하나 Delete 하는 Method 입니다.
@Transactional
public ResponseEntity<?> deleteGuestBook(HttpServletRequest request, Long guestBookId) {
Expand All @@ -293,7 +246,7 @@ public ResponseEntity<?> deleteGuestBook(HttpServletRequest request, Long guestB

guestBookRepository.delete(guestBook);

imageService.deleteImage(imageRepository.findByGuestBookId(guestBookId).orElseThrow(InvalidImageException::new).getId());
//imageService.deleteImage(imageRepository.findByGuestBookId(guestBookId).orElseThrow(InvalidImageException::new).getId());

ApiResponse apiResponse = ApiResponse.builder()
.check(true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.ttubeog.domain.guestbook.dto.request;

import com.ttubeog.domain.guestbook.domain.GuestBookType;
import lombok.Data;
import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;

@Data
@Getter
public class CreateGuestBookRequestDto {

Expand All @@ -16,6 +19,4 @@ public class CreateGuestBookRequestDto {

private Float star;

private String image;

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "GuestBook", description = "GuestBook API(방명록 API)")
@RequiredArgsConstructor
Expand Down Expand Up @@ -61,7 +62,7 @@ public class GuestBookController {
@ResponseStatus(value = HttpStatus.CREATED)
public ResponseEntity<?> createGuestBook(
@CurrentUser HttpServletRequest request,
@RequestBody CreateGuestBookRequestDto createGuestBookRequestDto
@RequestPart CreateGuestBookRequestDto createGuestBookRequestDto
) throws JsonProcessingException {
return guestBookService.createGuestBook(request, createGuestBookRequestDto);
}
Expand Down
Loading

0 comments on commit c31e179

Please sign in to comment.