Programming/Java
Spring Boot : 파일 업로드 구현
파란크리스마스
2025. 1. 31. 13:58
728x90
출처
application.properties
#File upload settings
# support multipart uploads (default: true)
spring.servlet.multipart.enabled=true
# Threshold at which files are written to memory (default: 0B)
#spring.servlet.multipart.file-size-threshold=0B
# Temporary storage space for uploaded files
spring.servlet.multipart.location=d:/usr/local/cnssm/resources
# Maximum size of the file (default: 1MB)
spring.servlet.multipart.max-file-size=10144MB
# Maximum size of request (default: 10MB)
spring.servlet.multipart.max-request-size=10144MB
FileStorageProperties.java
package com.bx.config.property;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "spring.servlet.multipart")
public class FileStorageProperties {
private String location;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
FileUploadController.java
package com.bx.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import com.bx.common.util.ExcelUtil;
import com.bx.config.property.FileStorageProperties;
import com.bx.service.FileStorageService;
@Controller
public class FileUploadController {
@Autowired
private FileStorageService fileStorageService;
@Autowired
private FileStorageProperties fileStorageProperties;
@RequestMapping(value = "/bx/uploadFile", method = RequestMethod.POST)
public String uploadFile(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
String fileName = fileStorageService.storeFile(file);
modelMap.put("fileName", fileName);
try {
if (fileName != null && (fileName.endsWith(".xls") || fileName.endsWith(".xlsx"))) {
FileInputStream fis = new FileInputStream(new File(fileStorageProperties.getLocation() + "/" + fileName));
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0); // 첫 번째 시트 가져오기
// 행 반복 (첫 번째 행부터 마지막 행까지)
for (Row row : sheet) {
// 열 반복 (첫 번째 열부터 마지막 열까지)
for (Cell cell : row) {
// 셀 값 출력
System.out.print(ExcelUtil.getCellValue(cell) + "\t");
}
System.out.println(); // 행 끝나면 줄바꿈
}
}
} catch (IOException e) {
e.printStackTrace();
}
return "bx/uploadOk";
}
@RequestMapping(value = "/uploadMultipleFiles", method = RequestMethod.POST)
public String uploadMultipleFiles(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
Arrays.asList(files).stream().map(file -> uploadFile(file, modelMap)).collect(Collectors.toList());
return "bx/uploadOk";
}
}
FileStorageService.java
package com.bx.service;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import com.bx.common.exception.FileNotFoundException;
import com.bx.common.exception.FileStorageException;
import com.bx.config.property.FileStorageProperties;
@Service
public class FileStorageService {
private final Path fileStorageLocation;
@Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) {
this.fileStorageLocation = Paths.get(fileStorageProperties.getLocation()).toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
// Check if the file's name contains invalid characters
if (fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public Resource loadFileAsResource(String fileName) {
try {
Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists()) {
return resource;
} else {
throw new FileNotFoundException("File not found " + fileName);
}
} catch (MalformedURLException ex) {
throw new FileNotFoundException("File not found " + fileName, ex);
}
}
}
FileNotFoundException.java
package com.bx.common.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class FileNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public FileNotFoundException(String message) {
super(message);
}
public FileNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
FileStorageException.java
package com.bx.common.exception;
public class FileStorageException extends RuntimeException {
private static final long serialVersionUID = 1L;
public FileStorageException(String message) {
super(message);
}
public FileStorageException(String message, Throwable cause) {
super(message, cause);
}
}
HTML
<form method="post" action="<c:url value="/cnssm/uploadFile"/>" enctype="multipart/form-data">
<div>
file : <input type="file" name="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
</div>
<input type="submit">
</form>