Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[File업로드] Servlet & File업로드 1 본문

인프런/[인프런] 스프링 MVC 2

[File업로드] Servlet & File업로드 1

Seung__ 2021. 10. 2. 15:31

1. Controller


@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";
    }
}

 

2. upload-form.html


<!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>

 

3. 사용


  • log
    • multipart/formdata 방식으로 전송
    • 상품명, 파일 두 개의 part가 있다
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePik1Rj6VKxGfAX9

------WebKitFormBoundaryePik1Rj6VKxGfAX9
Content-Disposition: form-data; name="itemName"

testName
------WebKitFormBoundaryePik1Rj6VKxGfAX9
Content-Disposition: form-data; name="file"; filename="TestTestTest.txt"
Content-Type: text/plain

ㄴ아ㅓㄴ오라넝로나어론아러ㅗㅁㄴ이ㅏ러ㅗㅁ니아러ㅗㅁㄴ이라ㅓㅗㅁ닝라ㅓㅗㅁㄴ이ㅏ러ㅗㅁ니아러ㅗㅁ니ㅏㅇ러ㅗㅁ니아러ㅗㅁ니아러ㅗㅁ니ㅏㅇ러
239ㅐ482739482734982739458ㅛ히ㅏㅓ오349ㅅ87ㅈ4ㅐ샤ㅏㅗㅓ3베94새87ㅁ34ㅔ9ㅅ8ㅐㅛ3ㅁ;4ㅐ샤ㅕㄷㄱㅅ
------WebKitFormBoundaryePik1Rj6VKxGfAX9--


2021-10-02 15:13:36.547  INFO 19384 --- [nio-8080-exec-5] h.u.c.ServletUploadControllerV1
	: request = org.springframework.web.multipart.support.StandardMultipartHttpServletRequest@7ef57b41
2021-10-02 15:13:36.548  INFO 19384 --- [nio-8080-exec-5] h.u.c.ServletUploadControllerV1
	: itemName = testName
2021-10-02 15:13:36.548  INFO 19384 --- [nio-8080-exec-5] h.u.c.ServletUploadControllerV1
	: parts = [org.apache.catalina.core.ApplicationPart@70329aef, 
    			org.apache.catalina.core.ApplicationPart@740d1031]

 

 

 

4. 멀티파트 사용 옵션

 

4.1 업로드 사이즈 제한


spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
  • 큰 파일을 무제한 업로드하게 둘 수는 없으므로 업로드 사이즈를 제한할 수 있다.
  • 사이즈를 넘으면 예외( SizeLimitExceededException )가 발생한다.
  • max-file-size : 파일 하나의 최대 사이즈, 기본 1MB
  • max-request-size : 멀티파트 요청 하나에 여러 파일을 업로드 할 수 있는데, 그 전체 합이다. 기본 10MB

 

4.2 spring.servlet.multipart.enabled 끄기


spring.servlet.multipart.enabled=false
  • 결과 로그
request=org.apache.catalina.connector.RequestFacade@xxx
itemName=null
parts=[]
  • 멀티파트는 일반적인 폼 요청인 application/x-www-form-urlencoded 보다 훨씬 복잡하다.
  • spring.servlet.multipart.enabled 옵션을 끄면 서블릿 컨테이너는 멀티파트와 관련된 처리를 하지 않음.
  • 그래서 결과 로그를 보면 request.getParameter("itemName") , request.getParts() 의 결과가 비어있음.
  • multipart에 대한 처리를 끔

 

4.3 spring.servlet.multipart.enabled 켜기


spring.servlet.multipart.enabled=true (기본 true)

 

  • 이 옵션을 켜면 스프링 부트는 서블릿 컨테이너에게 멀티파트 데이터를 처리하라고 설정한다. 
  • 참고로 기본 값은 true 이다.
request=org.springframework.web.multipart.support.StandardMultipartHttpServletRequest
itemName=Spring
parts=[ApplicationPart1, ApplicationPart2]

 

  • request.getParameter("itemName") 의 결과도 잘 출력되고, 
  • request.getParts() 에도 요청한 두 가지 멀티파트의 부분 데이터가 포함된 것을 확인할 수 있다. 
  • 이 옵션을 켜면 복잡한 멀티파트 요청을 처리해서 사용할 수 있게 제공한다.
  • 로그를 보면 HttpServletRequest 객체가 RequestFacade(기본)에서 
  • StandardMultipartHttpServletRequest 로 변한 것을 확인할 수 있다.

 

5. 참고 


  • spring.servlet.multipart.enabled 옵션을 켜면
  • 스프링의 DispatcherServlet 에서 멀티파트 리졸버( MultipartResolver )를 실행한다.
  • 멀티파트 리졸버는 멀티파트 요청인 경우
  • 서블릿 컨테이너가 전달하는 일반적인 HttpServletRequest 를 MultipartHttpServletRequest 로 변환해서 반환한다.
  • MultipartHttpServletRequest 는 HttpServletRequest 의 자식 인터페이스이고,
  • 멀티파트와 관련된 추가 기능을 제공한다.
  • 스프링이 제공하는 기본 멀티파트 리졸버는 MultipartHttpServletRequest 인터페이스를 구현한
  • StandardMultipartHttpServletRequest 를 반환한다.
  • 이제 컨트롤러에서 HttpServletRequest 대신에
  • MultipartHttpServletRequest 를 주입받을 수 있는데, 
  • 이것을 사용하면 멀티파트와 관련된 여러가지 처리를 편리하게 할 수 있다. 
  • 그런데 MultipartFile 이라는 것을 사용하는 것이 더 편함.
  • 따라서 MultipartHttpServletRequest 를 잘 사용하지는 않는다. 
  • 더 자세한 내용은 MultipartResolver 를 검색해보자.

 

6. GitHub : 211002 Servlet, FileUpload


 

GitHub - bsh6463/FileUpload

Contribute to bsh6463/FileUpload development by creating an account on GitHub.

github.com

 

Comments