Refactor: 한글 압축 파일 업로드 구현
This commit is contained in:
parent
cc37d3048f
commit
5a3b17b59a
@ -72,6 +72,9 @@ dependencies {
|
|||||||
|
|
||||||
// FCM
|
// FCM
|
||||||
implementation 'com.google.firebase:firebase-admin:7.1.1'
|
implementation 'com.google.firebase:firebase-admin:7.1.1'
|
||||||
|
|
||||||
|
// Apache Commons Compress
|
||||||
|
implementation 'org.apache.commons:commons-compress:1.21'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
@ -15,22 +15,24 @@ import com.worlabel.global.exception.ErrorCode;
|
|||||||
import com.worlabel.global.service.S3UploadService;
|
import com.worlabel.global.service.S3UploadService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||||
|
import org.apache.commons.compress.utils.IOUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -38,10 +40,10 @@ import java.util.zip.ZipInputStream;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class ImageService {
|
public class ImageService {
|
||||||
|
|
||||||
|
private final ProjectRepository projectRepository;
|
||||||
|
private final FolderRepository folderRepository;
|
||||||
private final S3UploadService s3UploadService;
|
private final S3UploadService s3UploadService;
|
||||||
private final ImageRepository imageRepository;
|
private final ImageRepository imageRepository;
|
||||||
private final FolderRepository folderRepository;
|
|
||||||
private final ProjectRepository projectRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이미지 리스트 업로드
|
* 이미지 리스트 업로드
|
||||||
@ -183,26 +185,28 @@ public class ImageService {
|
|||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apache Commons Compress 라이브러리를 사용하여 ZIP 파일을 처리
|
||||||
// 압축 파일을 임시 폴더에 압축 해제하는 메서드
|
|
||||||
private void unzip(MultipartFile zipFile, String destDir) throws IOException {
|
private void unzip(MultipartFile zipFile, String destDir) throws IOException {
|
||||||
try (ZipInputStream zis = new ZipInputStream(zipFile.getInputStream())) {
|
try (ZipArchiveInputStream zis = new ZipArchiveInputStream(zipFile.getInputStream(), "MS949")) {
|
||||||
ZipEntry zipEntry;
|
ArchiveEntry entry;
|
||||||
while ((zipEntry = zis.getNextEntry()) != null) {
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
ZipArchiveEntry zipEntry = (ZipArchiveEntry) entry;
|
||||||
Path newPath = zipSlipProtect(zipEntry, Paths.get(destDir));
|
Path newPath = zipSlipProtect(zipEntry, Paths.get(destDir));
|
||||||
|
|
||||||
if (zipEntry.isDirectory()) {
|
if (zipEntry.isDirectory()) {
|
||||||
Files.createDirectories(newPath);
|
Files.createDirectories(newPath);
|
||||||
} else {
|
} else {
|
||||||
Files.createDirectories(newPath.getParent());
|
Files.createDirectories(newPath.getParent());
|
||||||
Files.copy(zis, newPath);
|
try(OutputStream os = Files.newOutputStream(newPath)){
|
||||||
|
IOUtils.copy(zis, os);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zis.closeEntry();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 보안을 위해 압축 파일 경로를 보호하는 메서드
|
// 보안을 위해 압축 파일 경로를 보호하는 메서드
|
||||||
private Path zipSlipProtect(ZipEntry zipEntry, Path targetDir) throws IOException {
|
private Path zipSlipProtect(ZipArchiveEntry zipEntry, Path targetDir) throws IOException {
|
||||||
Path targetDirResolved = targetDir.resolve(zipEntry.getName());
|
Path targetDirResolved = targetDir.resolve(zipEntry.getName());
|
||||||
Path normalizePath = targetDirResolved.normalize();
|
Path normalizePath = targetDirResolved.normalize();
|
||||||
if (!normalizePath.startsWith(targetDir)) {
|
if (!normalizePath.startsWith(targetDir)) {
|
||||||
|
@ -78,11 +78,7 @@ public class ProjectController {
|
|||||||
@PostMapping("/projects/{project_id}/auto")
|
@PostMapping("/projects/{project_id}/auto")
|
||||||
public void autoLabeling(
|
public void autoLabeling(
|
||||||
@PathVariable("project_id") final Integer projectId,
|
@PathVariable("project_id") final Integer projectId,
|
||||||
@RequestBody final AutoModelRequest request,
|
@RequestBody final AutoModelRequest request) {
|
||||||
HttpServletRequest httpServletRequest) {
|
|
||||||
String clientIp = httpServletRequest.getRemoteAddr();
|
|
||||||
int clientPort = httpServletRequest.getRemotePort();
|
|
||||||
log.debug("클라이언트 IP: {}, 포트 번호: {}", clientIp, clientPort);
|
|
||||||
projectService.autoLabeling(projectId, request);
|
projectService.autoLabeling(projectId, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +167,9 @@ public class ProjectService {
|
|||||||
String endPoint = project.getProjectType().getValue() + "/predict";
|
String endPoint = project.getProjectType().getValue() + "/predict";
|
||||||
|
|
||||||
List<Image> imageList = imageRepository.findImagesByProjectIdAndPending(projectId);
|
List<Image> imageList = imageRepository.findImagesByProjectIdAndPending(projectId);
|
||||||
|
if(imageList.isEmpty()){
|
||||||
|
throw new CustomException(ErrorCode.DATA_NOT_FOUND);
|
||||||
|
}
|
||||||
List<AutoLabelingImageRequest> imageRequestList = imageList.stream()
|
List<AutoLabelingImageRequest> imageRequestList = imageList.stream()
|
||||||
.map(AutoLabelingImageRequest::of)
|
.map(AutoLabelingImageRequest::of)
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -8,7 +8,7 @@ import java.util.Objects;
|
|||||||
@Getter
|
@Getter
|
||||||
public class CustomException extends RuntimeException{
|
public class CustomException extends RuntimeException{
|
||||||
private final ErrorCode errorCode;
|
private final ErrorCode errorCode;
|
||||||
private Errors errors;
|
private final Errors errors;
|
||||||
|
|
||||||
public CustomException(ErrorCode errorCode) {
|
public CustomException(ErrorCode errorCode) {
|
||||||
this(errorCode, errorCode.getMessage(), null);
|
this(errorCode, errorCode.getMessage(), null);
|
||||||
|
Loading…
Reference in New Issue
Block a user