diff --git a/src/main/java/company/specialsource/controller/FileSyncController.java b/src/main/java/company/specialsource/controller/FileSyncController.java index b166b42..72cdf67 100644 --- a/src/main/java/company/specialsource/controller/FileSyncController.java +++ b/src/main/java/company/specialsource/controller/FileSyncController.java @@ -1,52 +1,59 @@ package company.specialsource.controller; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; - +import org.springframework.web.multipart.MultipartHttpServletRequest; +import java.io.InputStream; +import java.io.FileOutputStream; import java.io.File; -import java.io.IOException; @RestController -@RequestMapping("/api/sync") -@Slf4j public class FileSyncController { - // ⚠️ 나스 스토리지와 볼륨 마운트해 둔 백엔드 컨테이너 내부의 실제 저장 경로 - private final String NAS_STORAGE_PATH = "/app/storage/sync-folder/"; - - @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity uploadFileFromPhone(@RequestParam("file") MultipartFile file) { - if (file.isEmpty()) { - log.warn("⚠️ [Sync] 수신된 파일이 비어 있습니다."); - return ResponseEntity.badRequest().body("ERR: EMPTY_FILE"); - } + @PostMapping("/api/sync/upload") + public ResponseEntity uploadFile(HttpServletRequest request) { + String contentType = request.getContentType(); try { - // 저장 경로 폴더가 없으면 자동으로 생성 - File directory = new File(NAS_STORAGE_PATH); - if (!directory.exists()) { - directory.mkdirs(); - log.info("📁 [Sync] 업로드 저장 폴더를 새로 생성했습니다: {}", NAS_STORAGE_PATH); + // 1. 기존 웹 프론트엔드(Vue)에서 보낸 폼 데이터(Multipart) 처리 + if (contentType != null && contentType.startsWith("multipart/form-data")) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + MultipartFile multipartFile = multipartRequest.getFile("file"); + + if (multipartFile != null && !multipartFile.isEmpty()) { + // 💾 기존에 사용하시던 파일 저장 로직을 여기에 그대로 수행하면 됩니다. + // 예: multipartFile.transferTo(new File("기존 저장 경로")); + System.out.println("웹 프론트엔드로부터 멀티파트 파일 수신 완료: " + multipartFile.getOriginalFilename()); + } + } + // 2. MacroDroid 매크로에서 보낸 순수 바이너리 스트림(Octet-Stream 등) 처리 + else { + // 저장될 임시 파일명 정의 (타임스탬프 조합) + String fileName = "macro_sync_" + System.currentTimeMillis() + ".jpg"; + + // ⚠️ 유저님의 나스 환경에 맞는 실제 업로드 절대 경로를 입력해 주세요. + File targetFile = new File("/volume1/docker/upload_dir/" + fileName); + + try (InputStream is = request.getInputStream(); + FileOutputStream fos = new FileOutputStream(targetFile)) { + + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + fos.write(buffer, 0, bytesRead); + } + } + System.out.println("MacroDroid로부터 바이너리 파일 수신 및 저장 완료: " + fileName); } - // 핸드폰에서 온 원본 파일명 그대로 파일 객체 생성 - File destination = new File(directory, file.getOriginalFilename()); + return ResponseEntity.ok("Upload Success"); - // 물리 디스크(나스 HDD/SSD)에 실제 파일 쓰기 수행 - file.transferTo(destination); - - log.info("📱 [Sync] 스마트폰 동기화 완료! 파일명: {} (크기: {} bytes)", - file.getOriginalFilename(), file.getSize()); - - return ResponseEntity.ok("SUCCESS: INJECTED_TO_NAS"); - - } catch (IOException e) { - log.error("❌ [Sync] 나스 파일 저장 중 치명적 오류 발생", e); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("ERR: " + e.getMessage()); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.internalServerError().body("Upload Error: " + e.getMessage()); } } } \ No newline at end of file