ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링에서 컨트롤러로 넘어온 파일 저장하는 방법
    Knowledge/Spring 2019. 9. 18. 21:59
    반응형

    프론트 단에서 ajax로 파일을 서버로 넘기는 건 ( https://takeknowledge.tistory.com/60 ) 참고

     

    파일이 컨트롤러 단으로 넘어오면 파일을 저장하고

     

     

    나중에 사용할 수 있도록 파일 정보를 데이터베이스에 저장해야 한다.

     

     

    이걸 하는 방법은

     

    - 설정

     

    먼저 파일 처리에 필요한 라이브러리를 메이븐에 등록해줘야 한다. 파일은 Multipart ( HTTP프로토콜의 바디 부분에 데이터를 여러 부분으로 나눠서 보낸 것 ) 로 넘어오는데 HttpServletRequest는 웹 클라이언트가 전달하는 Multipart데이터를 쉽게 처리하는 메소드를 제공하지 않기 때문이다. 대표적인 파일 처리 라이브러리는 아파치 재단의 commons-fileupload 가 있다.  추가를 위해선

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.2.1</version>
            </dependency>
            
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.4</version>
            </dependency>
    cs

     

    메이븐에 이렇게 등록해주면 된다.

    이후엔 Spring에다가 MultipartResolver 설정을 해줘야 한다. 프로젝트의 Configuration 파일 ( 필자는 WebMvcContextConfiguration.java 가 이 설정 파일 이름이다 )  

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
        private final int FILE_MAX_UPLOAD_SIZE = 10485760// 1024 * 1024 * 10
        // 이 사이즌는 당연히 필요에 따라 변경하면 된다
     
        @Bean
        public MultipartResolver multipartResolver() {
            org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
            multipartResolver.setMaxUploadSize(FILE_MAX_UPLOAD_SIZE); 
            return multipartResolver;
        }
    cs

     

    이렇게 설정을 해주면 된다. 이러면 일단 설정은 끝이다. 그럼 이제 컨트롤러로 가자

     

    - 컨트롤러

     

    먼저 formData를 받기 위해선 @PostMapping이 사용되어야 한다. 그리고 파일은 MultipartFile 자료형(?)으로 받아야 하는데 파일이 하나면 MultipartFile, 파일이 여러개면 MultipartFile[] 을 활용해 배열로 받으면 된다.

     

    이후엔 두가지로 진행해주면 되는데

    1. Multipart의 메소드를 이용해서 파일 이름, 파일 크기등의 정보를 구해서 데이터 베이스에 저장하고

    2. 파일로부터 InputStream을 얻어 파일을 서버에 저장하면 된다.

     

    코드로 보자면

     

    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
    32
    33
    34
    35
    36
        @PostMapping("/upload")
        public String upload(@RequestParam("file") MultipartFile file) {
     
            System.out.println("파일 이름 : " + file.getOriginalFilename());
            System.out.println("파일 크기 : " + file.getSize());
            // 데이터 베이스에 정보를 저장하는 건
            // 이렇게 file의 get 메소드를 활용해 필요한 정보들을 가져오고 
            // 그걸 DTO에 담아 insert하면 된다. 
            // 간단한거니 후의 과정은 생략하고 파일로 서버에 저장하는 걸 보자면
     
            try (
                    // 맥일 경우
                    // FileOutputStream fos = new FileOutputStream("/tmp/" +file.getOriginalFilename());
                    // 윈도우일 경우
                    FileOutputStream fos = new FileOutputStream("c:/tmp/" + file.getOriginalFilename());
                    // 파일 저장할 경로 + 파일명을 파라미터로 넣고 fileOutputStream 객체 생성하고
                    InputStream is = file.getInputStream();) {
                    // file로 부터 inputStream을 가져온다.
                
                int readCount = 0;
                byte[] buffer = new byte[1024];
                // 파일을 읽을 크기 만큼의 buffer를 생성하고
                // ( 보통 1024, 2048, 4096, 8192 와 같이 배수 형식으로 버퍼의 크기를 잡는 것이 일반적이다.)
                
                while ((readCount = is.read(buffer)) != -1) {
                    //  파일에서 가져온 fileInputStream을 설정한 크기 (1024byte) 만큼 읽고
                    
                    fos.write(buffer, 0, readCount);
                    // 위에서 생성한 fileOutputStream 객체에 출력하기를 반복한다
                }
            } catch (Exception ex) {
                throw new RuntimeException("file Save Error");
            }
     
            return "uploadok";
        }
    cs

     

    위와 같이 처리하면 된다. 

     

    FileInputStream / FileOutputStream에 대한 자세한 설명과 

    어떤 과정을 거쳐 위와 같은 방법을 쓰게 되었는지는 아래 포스팅에 상세하게 나와있다. 

     

     

    [JAVA] ByteStream : FileInputStream / FileOutputStream

    ByteStream : FileInputStream / FileOutputStream 직접 키보드를 통하여 입력하는 데이터는 대개 임시 자료인 경우가 많다. 중요한 자료는 대부분 데이터베이스에 저장되어 있거나 파일 시스템에 저장된다. File..

    hyeonstorage.tistory.com

     

    반응형

    댓글

Designed by Tistory.