multipart/form-data

wangjh789·2022년 8월 17일
0

[Spring] 스프링-mvc-2

목록 보기
10/11

HTML 폼 전송방식 Content-Tpye

  • application/x-www-form-urlencoded
    HTML 폼 데이터를 서버로 전송하는 가장 기본적인 방법이다.문자를 전송하는 방식.
  • multipart/form-data
    파일 업로드를 위해 파일은 문자가 아니라 바이너리 데이터를 전송해야 한다.
    이름과 나이는 문자로 전송하고, 첨부파일은 바이너리로 전송해야 한다.
    enctype="multipart/form-data" 라고 명시해야 한다.
    <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>

httpRequest 의 로그를 보기 위해서 다음으로 설정해야 한다.
logging.level.org.apache.coyote.http11=debug

다음 설정은 한 파일당 크기 제한과 한 요청당 크기 제한을 설정하는 것이다.

spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB

다음과 같이 설정하면 기존 default request 구현체 였던 RequestFacade를 사용하도록 강제해 multipart 와 관련된 처리를 하지 않게끔 한다.
spring.servlet.multipart.enabled=false

multipart-form 을 쓰게 되면 StandardMultipartHttpServletRequest 구현체가 사용된다. 따라서 옵션을 true로 설정해 스프링부트가 서블릿 컨테이너에게 멀티파트 데이터를 처리하라고 지시해야한다.
서블릿 컨테이너에서 멀티파트 리졸버를 실행해 일반적인 HttpServletRequestMultipartHttpServletRequest로 변환해서 반환한다.
MultipartHttpServletRequestHttpServletRequest의 자식 인터페이스이고, 멀티파트와 관련된 추가 기능을 제공한다.

properties 파일 읽기

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

스프링에서 제공하는 @Value를 이용하자

part

multipartpart 요청의 경우 각 파트에도 header와 body로 구성되어 있다.

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

            log.info("submittedFileName = {}", part.getSubmittedFileName());
            log.info("size={}", part.getSize());

            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";
    }
request=org.springframework.web.multipart.support.StandardMultipartHttpServletRequest@1b225a15
itemName=Spring
parts=[org.apache.catalina.core.ApplicationPart@2eec8a8b, org.apache.catalina.core.ApplicationPart@4f37b7aa]
==== PART ====
name=itemName
header content-disposition:form-data; name="itemName"
submittedFileName = null
size=6
body=Spring
==== PART ====
name=file
header content-disposition:form-data; name="file"; filename="스크린샷 2022-07-12 오후 10.37.26.png"
header content-type:image/png
submittedFileName = 스크린샷 2022-07-12 오후 10.37.26.png
size=32789
body=�PNG ....
파일 저장 fullPath = /Users/MYNAME/Desktop/김영한-스프링/스프링 MVC - 2/스크린샷 2022-07-12 오후 10.37.26.png

위 로그에서 볼 수 있듯이 2개의 파트로 구성되어 있는 요청을 볼 수 있다.
해당 part가 파일인지 판단은 getSubmittedFileName!=null 로 간단하게 했다.
part는 쉽게 파일을 저장할 수 있게 write() 메서드도 제공한다.

profile
기록

0개의 댓글