Skip to content

Commit

Permalink
[Weekly/11/Feature/RestClientUtil] 유틸추가, 이미지 삭제 (#106)
Browse files Browse the repository at this point in the history
* feat: restClient, objectMapper util로 이동

* fix: 이미지 삭제

* feat: applicationTest 임시주석
  • Loading branch information
Daolove0323 authored Nov 10, 2024
1 parent b19cb75 commit a3a6bcc
Show file tree
Hide file tree
Showing 83 changed files with 394 additions and 370 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package org.ktc2.cokaen.wouldyouin.Image.api;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.ktc2.cokaen.wouldyouin.Image.api.dto.ImageResponse;
import org.ktc2.cokaen.wouldyouin.Image.application.ImageServiceFactory;
import org.ktc2.cokaen.wouldyouin.Image.application.ImageStorageService;
import org.ktc2.cokaen.wouldyouin._common.api.ApiResponse;
import org.ktc2.cokaen.wouldyouin._common.api.ApiResponseBody;
import org.ktc2.cokaen.wouldyouin._common.exception.FailToReadImageException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand All @@ -26,37 +22,31 @@

@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
@RequestMapping("/api/images")
public class ImageController {

private final ImageServiceFactory imageServiceFactory;
private final ImageStorageService imageStorageService;

@GetMapping(value = "/{directory}/{file}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE})
public ResponseEntity<byte[]> getImage(@PathVariable String directory, @PathVariable String file) {
return ResponseEntity.status(HttpStatus.OK).body(imageStorageService.readFromDirectory(Paths.get(directory, file)));
}

// Todo: authorize
@PostMapping("/images")
@PostMapping
public ResponseEntity<ApiResponseBody<List<ImageResponse>>> uploadImages(
@RequestParam List<MultipartFile> images,
@RequestParam(value = "type") ImageDomain imageDomain) {
return ApiResponse.ok(imageServiceFactory.getImageServiceByImageType(imageDomain).saveAndCreateImages(images));
}

// Todo: path 수정, service로 로직이동
@GetMapping(value = "images/{domain}/{path}", produces = {MediaType.IMAGE_PNG_VALUE, MediaType.IMAGE_JPEG_VALUE})
public ResponseEntity<byte[]> getImage(@PathVariable String domain, @PathVariable String path) {
try {
Resource resource = new ClassPathResource("static/images/" + domain + "/" + path);
System.out.println(Paths.get("static/images", domain, path));
return ResponseEntity.status(HttpStatus.OK).body(Files.readAllBytes(resource.getFile().toPath()));
} catch (IOException e) {
throw new FailToReadImageException("이미지를 읽어오는데 실패했습니다.");
}
return ApiResponse.ok(imageServiceFactory.getImageService(imageDomain).saveImages(images));
}

// Todo: authorize
@DeleteMapping("/images/{id}")
@DeleteMapping("/{id}")
public ResponseEntity<ApiResponseBody<Void>> deleteImage(
@PathVariable Long id,
@RequestParam(value = "type") ImageDomain imageDomain) {
imageServiceFactory.getImageServiceByImageType(imageDomain).deleteAndDelete(id);
imageServiceFactory.getImageService(imageDomain).deleteAndDelete(id);
return ApiResponse.noContent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
@RequiredArgsConstructor
public class AdvertisementImageService extends ImageService<AdvertisementImage> {

private final ImageStorage imageStorage;
@Value("${image.upload.ad.child-path}")
private String childPath;
private final ImageStorageService imageStorageService;
private final AdvertisementImageRepository adImageRepository;
@Value("${image.upload.ad.sub-path}")
private String subPath;

@Override
protected ImageRepository<AdvertisementImage> getImageRepository() {
Expand All @@ -32,8 +32,8 @@ protected ImageDomain getImageDomain() {
}

@Override
protected String getSubPath() {
return subPath;
protected String getChildPath() {
return childPath;
}

@Override
Expand All @@ -45,13 +45,12 @@ protected AdvertisementImage toEntity(ImageRequest imageRequest) {
}

@Transactional
public AdvertisementImage saveAndCreateImage(MultipartFile image) {
String path = imageStorage.save(image, getSubPath());
return adImageRepository.save(toEntity(ImageRequest.of(path, image.getSize(), ImageStorage.getExtension(image))));
public AdvertisementImage saveImage(MultipartFile image) {
return adImageRepository.save(toEntity(imageStorageService.saveToDirectory(image, getChildPath())));
}

@Transactional
public void setAd(AdvertisementImage image, Advertisement ad) {
public void setAdvertisement(AdvertisementImage image, Advertisement ad) {
image.setAdvertisement(ad);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
@RequiredArgsConstructor
public class CurationImageService extends ImageService<CurationImage> {

@Value("${image.upload.curation.child-path}")
private String childPath;
private final CurationImageRepository curationImageRepository;

@Value("${image.upload.curation.sub-path}")
private String subPath;

@Override
public ImageRepository<CurationImage> getImageRepository() {
return curationImageRepository;
Expand All @@ -31,8 +30,8 @@ protected ImageDomain getImageDomain() {
}

@Override
protected String getSubPath() {
return subPath;
protected String getChildPath() {
return childPath;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
@Service
public class EventImageService extends ImageService<EventImage> {

@Value("${image.upload.event.child-path}")
private String childPath;
private final EventImageRepository eventImageRepository;

@Value("${image.upload.event.sub-path}")
private String subPath;

@Override
public ImageRepository<EventImage> getImageRepository() {
return eventImageRepository;
Expand All @@ -31,13 +30,16 @@ protected ImageDomain getImageDomain() {
}

@Override
protected String getSubPath() {
return subPath;
protected String getChildPath() {
return childPath;
}

@Override
protected EventImage toEntity(ImageRequest imageRequest) {
return EventImage.builder().url(imageRequest.getUrl()).size(imageRequest.getSize()).build();
return EventImage.builder()
.url(imageRequest.getUrl())
.size(imageRequest.getSize())
.build();
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public abstract class ImageService<T extends Image> {

@Autowired
protected ImageStorage imageStorage;
protected ImageStorageService imageStorageService;

@Value("${spring.wouldyouin-domain-name}")
private String domainName;
Expand All @@ -28,7 +28,7 @@ public abstract class ImageService<T extends Image> {

protected abstract ImageDomain getImageDomain();

protected abstract String getSubPath();
protected abstract String getChildPath();

protected abstract T toEntity(ImageRequest imageRequest);

Expand All @@ -47,19 +47,16 @@ protected void delete(Long id) {
}

@Transactional
public List<ImageResponse> saveAndCreateImages(List<MultipartFile> images) {
public List<ImageResponse> saveImages(List<MultipartFile> images) {
return images.stream()
.map(image -> {
String path = imageStorage.save(image, getSubPath());
return create(ImageRequest.of(path, image.getSize(), ImageStorage.getExtension(image)));
})
.map(image -> create(imageStorageService.saveToDirectory(image, getChildPath())))
.toList();
}

@Transactional
public void deleteAndDelete(Long id) {
T image = getById(id);
delete(id);
imageStorage.delete(image.getUrl());
imageStorageService.delete(image.getUrl());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.ktc2.cokaen.wouldyouin.Image.api.ImageDomain;
import org.ktc2.cokaen.wouldyouin.Image.persist.Image;
Expand All @@ -10,14 +11,14 @@
@Component
public class ImageServiceFactory {

private final ConcurrentHashMap<ImageDomain, ImageService<? extends Image>> imageTypeToImageServiceMap;
private final ConcurrentHashMap<ImageDomain, ImageService<? extends Image>> imageServiceMap;

public ImageServiceFactory(List<ImageService<? extends Image>> imageServices) {
imageTypeToImageServiceMap = new ConcurrentHashMap<>(imageServices.stream()
.collect(Collectors.toConcurrentMap(ImageService::getImageDomain, imageService -> imageService)));
imageServiceMap = new ConcurrentHashMap<>(imageServices.stream()
.collect(Collectors.toConcurrentMap(ImageService::getImageDomain, Function.identity())));
}

public ImageService<? extends Image> getImageServiceByImageType(ImageDomain imageDomain) {
return imageTypeToImageServiceMap.get(imageDomain);
public ImageService<? extends Image> getImageService(ImageDomain imageDomain) {
return imageServiceMap.get(imageDomain);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.ktc2.cokaen.wouldyouin.Image.application;

import java.nio.file.Path;
import java.nio.file.Paths;
import lombok.RequiredArgsConstructor;
import org.ktc2.cokaen.wouldyouin.Image.api.dto.ImageRequest;
import org.ktc2.cokaen.wouldyouin._common.exception.FailedToUploadImageException;
import org.ktc2.cokaen.wouldyouin._common.util.FileUtil;
import org.ktc2.cokaen.wouldyouin._common.util.RestClientUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
@RequiredArgsConstructor
public class ImageStorageService {

@Value("${image.upload.parent-path}")
private String parentPath;
private final RestClientUtil client;

public byte[] readFromDirectory(Path path) {
return FileUtil.readFile(Paths.get(parentPath).resolve(path));
}

public ImageRequest saveToDirectory(MultipartFile image, String subPath) {
String extension = FileUtil.getExtension(image);
String fileName = FileUtil.generateUuidName() + "." + extension;
Path path = Paths.get(parentPath, subPath, fileName);
FileUtil.saveFile(image, path);
return ImageRequest.of(path.toString(), image.getSize(), FileUtil.getExtension(image));
}

public ImageRequest saveToDirectory(String imageUrl, String subPath) {
ResponseEntity<byte[]> response = client.get(imageUrl, byte[].class);
if (response.getBody() == null) {
throw new FailedToUploadImageException("응답 본문이 비어있어 이미지를 가져올 수 없습니다.");
}
if (!response.getStatusCode().is2xxSuccessful()) {
throw new FailedToUploadImageException("이미지 URL에 대한 요청을 실패하였습니다.");
}
String extension = FileUtil.getExtension(imageUrl);
String fileName = FileUtil.generateUuidName() + "." + extension;
Path path = Paths.get(parentPath, subPath, fileName);
FileUtil.saveFile(response.getBody(), path);
long size = response.getBody().length;
return ImageRequest.of(path.toString(), size, extension);
}

public void delete(String imagePath) {
FileUtil.deleteFile(Paths.get(imagePath));
}
}
Loading

0 comments on commit a3a6bcc

Please sign in to comment.