From 059d690c939050ff2e4a4f4a5517783d053071a6 Mon Sep 17 00:00:00 2001 From: sdw086 Date: Fri, 22 May 2026 16:40:22 +0900 Subject: [PATCH] =?UTF-8?q?[api]=20FileController.java=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=A4=EC=85=98=20=EB=A7=9E=EC=B6=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alist/api/config/OpenApiConfig.java | 4 +- .../com/alist/api/config/SecurityConfig.java | 2 +- .../config/jwt/JwtAuthenticationFilter.java | 2 +- .../api/modules/file/FileController.java | 54 ++++++++++--------- .../api/modules/file/service/FileService.java | 12 +++-- 5 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/alist/api/config/OpenApiConfig.java b/src/main/java/com/alist/api/config/OpenApiConfig.java index 00c6091..18dd57a 100644 --- a/src/main/java/com/alist/api/config/OpenApiConfig.java +++ b/src/main/java/com/alist/api/config/OpenApiConfig.java @@ -44,7 +44,7 @@ public class OpenApiConfig { .pathsToExclude( "/admin/**" , "/cors/**" - , "/files/**" + , "/file/**" , "/tusFiles/**" , "/error" , "/actuator/**" @@ -66,7 +66,7 @@ public class OpenApiConfig { .group("900. common") .pathsToMatch( "/cors/**" - , "/files/**" + , "/file/**" , "/tusFiles/**" ) .build(); diff --git a/src/main/java/com/alist/api/config/SecurityConfig.java b/src/main/java/com/alist/api/config/SecurityConfig.java index f8f2bc0..407f958 100644 --- a/src/main/java/com/alist/api/config/SecurityConfig.java +++ b/src/main/java/com/alist/api/config/SecurityConfig.java @@ -90,7 +90,7 @@ public class SecurityConfig { , "/user/migrationUserList" , "/tusFiles/tusHook" , "/tusFiles/uploadAuth" - , "/files/**" + , "/file/**" ).permitAll() .anyRequest().authenticated() ) diff --git a/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java b/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java index ee72c78..3989ea4 100644 --- a/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/alist/api/config/jwt/JwtAuthenticationFilter.java @@ -28,7 +28,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { try { String requestUri = request.getRequestURI(); boolean adminRequest = requestUri.startsWith("/admin/"); - boolean sharedRequest = requestUri.startsWith("/tusFiles/") || requestUri.startsWith("/files/") || requestUri.startsWith("/cors/"); + boolean sharedRequest = requestUri.startsWith("/tusFiles/") || requestUri.startsWith("/file/") || requestUri.startsWith("/cors/"); String token = resolveToken(request, adminRequest, sharedRequest); if (token != null && jwtTokenProvider.validateToken(token)) { diff --git a/src/main/java/com/alist/api/modules/file/FileController.java b/src/main/java/com/alist/api/modules/file/FileController.java index b1cb775..64e3e05 100644 --- a/src/main/java/com/alist/api/modules/file/FileController.java +++ b/src/main/java/com/alist/api/modules/file/FileController.java @@ -17,11 +17,11 @@ import java.util.ArrayList; import java.util.List; @Tag( - name = "902. 파일 업로드", - description = "DB 기록 없이 파일을 저장하고 uploadPath를 반환하는 단순 업로드 API입니다. SunEditor 이미지는 file-domain URL을 반환합니다." + name = "902. 파일 업로드" + , description = "DB 기록 없이 파일을 저장하고 uploadPath를 반환하는 단순 업로드 API입니다. SunEditor 이미지는 file-domain URL을 반환합니다." ) @RestController -@RequestMapping("/files") +@RequestMapping("/file") public class FileController { private final FileService fileService; @@ -30,75 +30,79 @@ public class FileController { } @Operation( - summary = "단순 파일 업로드", - description = """ + summary = "단순 파일 업로드" + , description = """ DB에 기록하지 않고 파일만 저장합니다. 반환된 uploadPath는 이후 각 업무 테이블에 저장해서 view/download 경로로 사용할 수 있습니다. folder 값은 저장 폴더 키이며, 설정된 타입이면 해당 정책을 사용하고 설정되지 않은 값이면 전역 정책만 적용합니다. """ ) @PostMapping("/upload") - public ResponseEntity> upload( - @RequestParam String folder, - @RequestPart MultipartFile file + public ResponseEntity> fileUpload( + @RequestParam String folder + , @RequestPart MultipartFile file ) { - FileUploadVo result = fileService.upload(folder, file); - return ApiResponse.entity(result, ApiResponseCode.CODE_200); + FileUploadVo fileUploadVo = fileService.saveFileUpload(folder, file); + return ApiResponse.entity(fileUploadVo, ApiResponseCode.CODE_200); } @Operation( - summary = "SunEditor 이미지 업로드", - description = """ + summary = "SunEditor 이미지 업로드" + , description = """ SunEditor 이미지 업로드 전용 API입니다. 업로드 파일을 저장한 뒤 SunEditor가 요구하는 result 배열 형태로 응답합니다. 응답 URL은 file.upload.view.file-domain 값과 uploadPath를 조합한 공개 file-domain URL입니다. """ ) @PostMapping("/suneditor/upload") - public ResponseEntity sunEditorUpload( - @RequestParam(value = "folder", defaultValue = "editor") String folder, - MultipartHttpServletRequest request + public ResponseEntity fileSunEditorUpload( + @RequestParam(value = "folder", defaultValue = "editor") String folder + , MultipartHttpServletRequest request ) { - List result = new ArrayList<>(); + List sunEditorUploadItemList = new ArrayList<>(); for (MultipartFile file : request.getFileMap().values()) { - FileUploadVo uploaded = fileService.upload(folder, file); + FileUploadVo uploaded = fileService.saveFileUpload(folder, file); String imageUrl = fileService.buildImageUrl(uploaded.getUploadPath()); - result.add(new SunEditorUploadVo.Item( + sunEditorUploadItemList.add(new SunEditorUploadVo.Item( imageUrl, uploaded.getOriginalFileName(), uploaded.getFileSize() )); } - return ResponseEntity.ok(new SunEditorUploadVo(result)); + return ResponseEntity.ok(new SunEditorUploadVo(sunEditorUploadItemList)); } @Operation( - summary = "파일 보기", - description = """ + summary = "파일 보기" + , description = """ uploadPath 기준으로 파일을 inline 응답합니다. 예: /uploads/notice/2026/05/08/sample.png 단순 업로드 결과의 uploadPath를 그대로 path 파라미터에 전달합니다. """ ) @GetMapping("/view") - public ResponseEntity view(@RequestParam String path) { + public ResponseEntity fileView( + @RequestParam String path + ) { return fileService.resource(path, true); } @Operation( - summary = "파일 다운로드", - description = """ + summary = "파일 다운로드" + , description = """ uploadPath 기준으로 파일을 attachment 응답합니다. 예: /uploads/notice/2026/05/08/sample.pdf 단순 업로드 결과의 uploadPath를 그대로 path 파라미터에 전달합니다. """ ) @GetMapping("/download") - public ResponseEntity download(@RequestParam String path) { + public ResponseEntity fileDownload( + @RequestParam String path + ) { return fileService.resource(path, false); } } diff --git a/src/main/java/com/alist/api/modules/file/service/FileService.java b/src/main/java/com/alist/api/modules/file/service/FileService.java index 93166b3..89d8575 100644 --- a/src/main/java/com/alist/api/modules/file/service/FileService.java +++ b/src/main/java/com/alist/api/modules/file/service/FileService.java @@ -4,14 +4,18 @@ import com.alist.api.modules.file.properties.FileUploadProperties; import com.alist.api.modules.file.vo.FileUploadVo; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; -import org.springframework.http.*; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.util.UriComponentsBuilder; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.LocalDate; import java.util.Locale; import java.util.UUID; @@ -28,7 +32,7 @@ public class FileService { this.fileUploadImageService = fileUploadImageService; } - public FileUploadVo upload(String folder, MultipartFile file) { + public FileUploadVo saveFileUpload(String folder, MultipartFile file) { if (folder == null || folder.isBlank()) throw new IllegalArgumentException("invalid folder"); if (file == null || file.isEmpty()) throw new IllegalArgumentException("empty file");