[스프링 MVC - 2편] 파일 업로드

지현·2022년 1월 10일
0

스프링

목록 보기
32/32

파일 업로드 소개

HTML 폼 전송 방식

  • Content-Type: application/x-www-form-urlencoded

    • HTML 폼 데이터를 서버로 전송하는 가장 기본적인 방법
    • 폼에 입력한 전송할 항목을 HTTP Body에 문자로 & 로 구분해서 전송
  • enctype="multipart/form-data"

    • 문자와 바이너리를 동시에 전송할 수 있음 > 파일 전송 가능
    • 각각의 항목을 구분해서, 한번에 전송하는 것
    • boundary에 지정한 값을 기반으로 구분이 됨
    • 구분된 값 별로 헤더값과 바디값이 들어감
    • 여러개의 다른 스타일의 데이터를 한번에 보낼 수 있음

서블릿과 파일 업로드

upload-form.html

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

ServletUploadControllerV1.java

    @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";
    }
  • request.getParts() : multipart/form-data 전송 방식에서 각각 나누어진 부분을 받아서 확인할 수 있음

멀티파트 사용 옵션

spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
  • max-file-size : 파일 하나의 최대 사이즈, 기본 1MB
  • max-request-size : 멀티파트 요청 하나에 여러 파일을 업로드 할 수 있는데 그 전체 합, 기본 10MB
spring.servlet.multipart.enabled=true
  • 기본값은 true
  • 해당 옵션을 끄면 멀티파트와 관련된 처리를 하지 X

파일 업로드

application.properties

file.dir=파일 업로드 경로 설정

ServletUploadControllerV2.java


    @Value("${file.dir}") 
    //application.properties에 있는 속성 그대로 가져오기
    private String fileDir;
    
    @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 ====");
            
            ...
            
            //데이터 읽기
            InputStream inputStream = part.getInputStream();
            String body = StreamUtils.copyToString(inputStream, 
            						StandardCharsets.UTF_8);
            log.info("body={}",body);
   
            //파일에 저장하기
            if(StringUtils.hasText(part.getSubmittedFileName())){
                //SubmittedFileName이 있는지?

                String fullPath = fileDir + part.getSubmittedFileName();
                log.info("파일 저장 fullPath={}",fullPath);
                part.write(fullPath);
            }


        }

        return "upload-form";
    }
  • part.getSubmittedFileName() : 클라이언트가 전달한 파일명
  • part.getInputStream() : Part의 전송 데이터를 읽을 수 있음
  • part.write(...) : Part를 통해 전송된 데이터를 저장할 수 있음

스프링과 파일 업로드

스프링은 MultipartFile이라는 인터페이스로 멀티파트 파일을 매우 편리하게 지원

    @Value("${file.dir}") //application.properties에 있는 속성 그대로 가져오기
    private String fileDir;

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

    @PostMapping("/upload")
    public String saveFile(@RequestParam String itemName,
                           @RequestParam MultipartFile file,
                           HttpServletRequest request) throws IOException {
        log.info("request={}",request);
        log.info("itemName={}",itemName);
        log.info("multipartFile={}",file);

        if(!file.isEmpty()){
            String fullPath = fileDir + file.getOriginalFilename(); 
            //스프링이 제공하는 기능
            log.info("파일 저장 fullPath={}",fullPath);
            file.transferTo(new File(fullPath));
        }

        return "upload-form";
    }
  • file.getOriginalFilename() : 업로드 파일 명
  • file.transferTo(...) : 파일 저장



출처
[인프런] 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

0개의 댓글