File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package kr.itn.itnhub.seed;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@RestController
public class SeedController {
private final SeedService seedService;
public SeedController(SeedService seedService) {
this.seedService = seedService;
}
@PostMapping("/api/seed")
public SeedReport upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
throw new SeedParseException("업로드된 파일이 비어 있습니다.");
}
// 확장자 검사만으로 파일 형식을 완전히 보장하진 못하지만, 엉뚱한 바이트를
// 곧장 Apache POI에 넘기기 전에 흔한 실수(다른 파일을 잘못 올림)를 걸러내고
// 사람이 이해할 수 있는 메시지로 알려준다.
String filename = file.getOriginalFilename();
if (filename == null || !hasAllowedExtension(filename)) {
throw new SeedParseException("엑셀 파일(.xlsx 또는 .xlsm)만 업로드할 수 있습니다.");
}
// IOException을 그대로 던지면 바디 없는 500이 되어 다른 업로드 오류와 다르게
// 취급된다. 스트림 읽기 실패도 사용자가 이해할 수 있는 400으로 통일한다.
try (InputStream in = file.getInputStream()) {
return seedService.seed(in);
} catch (IOException e) {
throw new SeedParseException("엑셀 파일을 읽지 못했습니다.", e);
}
}
private static boolean hasAllowedExtension(String filename) {
String lower = filename.toLowerCase();
return lower.endsWith(".xlsx") || lower.endsWith(".xlsm");
}
}