[api] FileController.java 컨벤션 맞춰 변경

This commit is contained in:
2026-05-22 16:40:22 +09:00
parent 24783da7a0
commit 059d690c93
5 changed files with 41 additions and 33 deletions
@@ -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();
@@ -90,7 +90,7 @@ public class SecurityConfig {
, "/user/migrationUserList"
, "/tusFiles/tusHook"
, "/tusFiles/uploadAuth"
, "/files/**"
, "/file/**"
).permitAll()
.anyRequest().authenticated()
)
@@ -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)) {
@@ -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<ApiResponse<FileUploadVo>> upload(
@RequestParam String folder,
@RequestPart MultipartFile file
public ResponseEntity<ApiResponse<FileUploadVo>> 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<SunEditorUploadVo> sunEditorUpload(
@RequestParam(value = "folder", defaultValue = "editor") String folder,
MultipartHttpServletRequest request
public ResponseEntity<SunEditorUploadVo> fileSunEditorUpload(
@RequestParam(value = "folder", defaultValue = "editor") String folder
, MultipartHttpServletRequest request
) {
List<SunEditorUploadVo.Item> result = new ArrayList<>();
List<SunEditorUploadVo.Item> 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<Resource> view(@RequestParam String path) {
public ResponseEntity<Resource> 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<Resource> download(@RequestParam String path) {
public ResponseEntity<Resource> fileDownload(
@RequestParam String path
) {
return fileService.resource(path, false);
}
}
@@ -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");