Spring boot - Part 객체를 이용한 파일 업로드

목차

Spring boot 파일 업로드

Form 태그에 enctype 옵션으로 multipart/form-data 를 명시하면 파일을 보낼 수 있다.

<form th:action method="post" enctype="multipart/form-data">
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
</head>
<body>
<div class="container">

<div class="py-5 text-center">
<h2>상품 등록 폼</h2>
</div>
<h4 class="mb-3">상품 입력</h4>
<form th:action method="post" enctype="multipart/form-data">
<ul>
<li>상품명 <input type="text" name="itemName"></li>
<li>파일<input type="file" name="file" ></li>
</ul>
<input type="submit"/>
</form>

</div> <!-- /container -->
</body>
</html>

Part 인터페이스

Servlet 에서는 HTTP 멀티파트 요청을 처리하기 위해 Part 인터페이스를 제공합니다.

  • getHeaderNames()
    • part Type으로 전달된 데이터의 모든 해더 이름을 가져온다.
  • getContentType()
    • 파일의 ContentType을 가져온다.
  • getHeader(headerName)
    • getHeader메소드에 헤더 이름을 넘겨주면 해더 이름이 갖는 요청의 모든 해더 정보를 가져온다.
  • getSubmittedFileName()
    • 파일 명을 가져오기 위한 메소드
  • getInputStream()
    • Part에 저장된 데이터를 가져오기 위한 메소드
  • write(filepath)
    • write 메소드에 파일이 저장될 File Path를 입력하면 해당 경로에 파일이 저장하는 메소드
public interface Part {
InputStream getInputStream() throws IOException;

String getContentType();

String getName();

String getSubmittedFileName();

long getSize();

void write(String var1) throws IOException;

void delete() throws IOException;

String getHeader(String var1);

Collection<String> getHeaders(String var1);

Collection<String> getHeaderNames();
}

Request 객체내 파일 정보 가져오기

HttpServletRequest 객체내 getParts 메소드를 통해 Part 객체들을 얻어올 수 있다.

public String saveFileV1(HttpServletRequest request) throws ServletException, IOException{
...
Collection<Part> parts = request.getParts();
@Slf4j
@Controller
@RequestMapping("/servlet/v1")
public class ServletUploadControllerV1 {

@GetMapping("upload")
public String newFile(){
return "upload-form";
}

@PostMapping("upload")
public String saveFileV1(HttpServletRequest request) throws ServletException, IOException{
log.info("request={}", request);

String itemName = request.getParameter("itemName");
log.info("itemName={}", itemName);

Collection<Part> parts = request.getParts();
log.info("parts={}", parts);

return "upload-form";
}
}

Part 객체를 통해 파일 정보 가져오기

Collection<Part> parts = request.getParts();
log.info("parts={}", parts);

for (Part part : parts) {
log.info("==== PART ====");
log.info("name={}", part.getName());
Collection<String> headerNames = part.getHeaderNames();
for (String headerName : headerNames) {
log.info("header {}: {}", headerName, part.getHeader(headerName));
}
//편의 메서드
//content-disposition; filename
log.info("submittedFilename={}", part.getSubmittedFileName());
log.info("size={}", part.getSize()); //part body size

//데이터 읽기
InputStream inputStream = part.getInputStream();
String body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("body={}", body);

//파일에 저장하기
if (StringUtils.hasText(part.getSubmittedFileName())) {
String fullPath = fileDir + part.getSubmittedFileName();
log.info("파일 저장 fullPath={}", fullPath);
part.write(fullPath);
}
}
@Slf4j
@Controller
@RequestMapping("/servlet/v2")
public class ServletUploadControllerV2 {

@Value("${file.dir}")
private String fileDir;

@GetMapping("/upload")
public String newFile() {
return "upload-form";
}

@PostMapping("/upload")
public String saveFileV1(HttpServletRequest request) throws ServletException, IOException {
log.info("request={}", request);

String itemName = request.getParameter("itemName");
log.info("itemName={}", itemName);

Collection<Part> parts = request.getParts();
log.info("parts={}", parts);

for (Part part : parts) {
log.info("==== PART ====");
log.info("name={}", part.getName());
Collection<String> headerNames = part.getHeaderNames();
for (String headerName : headerNames) {
log.info("header {}: {}", headerName, part.getHeader(headerName));
}
//편의 메서드
//content-disposition; filename
log.info("submittedFilename={}", part.getSubmittedFileName());
log.info("size={}", part.getSize()); //part body size

//데이터 읽기
InputStream inputStream = part.getInputStream();
String body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("body={}", body);

//파일에 저장하기
if (StringUtils.hasText(part.getSubmittedFileName())) {
String fullPath = fileDir + part.getSubmittedFileName();
log.info("파일 저장 fullPath={}", fullPath);
part.write(fullPath);
}
}

return "upload-form";
}
}
Share