본문 바로가기

프로그래밍/Spring & MyBatis

[Spring] Upload (단일/다중)

단일파일 다중파일 업로드하기

파일 업로드를 구현해야하는 개발일이 생겨서 파일 업로드를 구현해보았습니다.

파일 업로드를 구현하기 위한 절차를 간략하게 정리해보았습니다.!

1. pom.xml설정

2. servlet-context.xml 설정

3. jsp 코드 작성

4. controller 코드 작성


pom.xml 설정

먼저 pom에 파일업로드를 하기 위한 dependency를 추가합니다. 저는 여기서 추가된 라이브러리를 통해 파일 업로드를 구현하였습니다.


         <!-- Commons FileUpload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.2</version>
        </dependency>
         
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>


servlet-context.xml 설정

추가된 라이브러리에 bean설정을 진행합니다.

maxUploadSize 프로퍼티는 업로드 되는 파일의 크기를 설정할 수 있는데 저는 이미지만 업로드 하기 위해 파일 크기가 5MB를 넘길 수 없게 설정하였습니다.


    <!-- file Upload -->
    <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- max upload size in bytes -->
        <beans:property name="maxUploadSize" value="5242880" /> <!-- 5MB -->
        <!-- max size of file in memory (in bytes) -->
        <beans:property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
    </beans:bean>


CommonsMultipartResolver 설정

 Property

 Type 

 Description 

 maxUploadSize

 Long

 최대 업로드 가능한 바이트 크기, -1은 제한이 없음을 의미합니다. Default(-1)

 maxInMemorySize

 int

 디스크에 임시 파일을 생성하기 전에 메모리에 보관할 수 있는 최대 바이트 크기, 기본 값은 10240 바이트입니다.

 defaultEncording

 String 

 요청을 파싱할 때 사용할 캐릭터 인코딩, 지정하지 않은 경우 HttpServletRequest.setEncording() 메서드로 지정한 캐릭터 셋이 사용됩니다. 아무 값도 없을 경우 ISO-8859-1을 사용합니다.



JSP 소스

파일을 업로드 하기 위해서 form에 enctype="multipart/form-data" 속성을 추가합니다.

단일파일일 경우 type=file만 추가하면 되지만 다중 파일일 경우에는 multiple="multiple" 속성이 추가되어야 합니다.


<input type="file" name="file" />


<input multiple="multiple" type="file" name="file" />


1. 단일 파일 업로드일 경우


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form name="fileForm" action="requestupload1" method="post" enctype="multipart/form-data">
        <input type="file" name="file" />
        <input type="text" name="src" />
        <input type="submit" value="전송" />
    </form>
</body>
</html>


2. 다중 파일 업로드일 경우


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form name="fileForm" action="requestupload2" method="post" enctype="multipart/form-data">
        <input multiple="multiple" type="file" name="file" />
        <input type="text" name="src" />
        <input type="submit" value="전송" />
    </form>
</body>
</html>


Controller 소스


    @RequestMapping(value = "requestupload1")
    public String requestupload1(MultipartHttpServletRequest mtfRequest) {
        String src = mtfRequest.getParameter("src");
        System.out.println("src value : " + src);
        MultipartFile mf = mtfRequest.getFile("file");

        String path = "C:\\image\\";

        String originFileName = mf.getOriginalFilename(); // 원본 파일 명
        long fileSize = mf.getSize(); // 파일 사이즈

        System.out.println("originFileName : " + originFileName);
        System.out.println("fileSize : " + fileSize);

        String safeFile = path + System.currentTimeMillis() + originFileName;

        try {
            mf.transferTo(new File(safeFile));
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return "redirect:/";
    }
    
    @RequestMapping(value = "requestupload2")
    public String requestupload2(MultipartHttpServletRequest mtfRequest) {
        List<MultipartFile> fileList = mtfRequest.getFiles("file");
        String src = mtfRequest.getParameter("src");
        System.out.println("src value : " + src);

        String path = "C:\\image\\";

        for (MultipartFile mf : fileList) {
            String originFileName = mf.getOriginalFilename(); // 원본 파일 명
            long fileSize = mf.getSize(); // 파일 사이즈

            System.out.println("originFileName : " + originFileName);
            System.out.println("fileSize : " + fileSize);

            String safeFile = path + System.currentTimeMillis() + originFileName;
            try {
                mf.transferTo(new File(safeFile));
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return "redirect:/";
    }


파일 사이즈와, 원본 파일 이름을 가져올 수있는 API가 주석에 있으니 참고하면 될 것같습니다.

저는 mf.tramsferTo를 사용하여 파일을 저장하였지만, MultipartFile에서는 getByte() 메서드로 파일을 가져올 수 있습니다.

가져온 파일의 byte[]로 OutputStream을 이용하여 파일 저장도 가능합니다.


다중파일과 단일파일의 소스 차이

getFile일 경우는 단일파일, getFiles일 경우는 다중 파일을 List<MultipartFile>로 가져오게 됩니다.


실행결과

아래와 같이 잘 올라가고 있습니다.

예제 소스 첨부합니다.




 SpringFileUploadSample.zip



출처: http://ktko.tistory.com/129?category=703665 [KTKO 개발 블로그와 여행 일기]