[국비학원 기록/Spring] 스프링 CommonsMultipartResolver - 다중 파일 업로드, 썸네일 이미지 이용
my code archive
article thumbnail
반응형

스프링 파일 업로드 처리 - MultipartResolver

 

  • 스프링이 제공하는 MultiPartResolver 가 바로 CommonsMultipartResolver, 여러개의 파일 한꺼번에 업로드 가능
  •  Commons FileUpload API를 이용해서 Multipart를 처리해준다.

 

연습1. 다중 파일 업로드

 

1. pom.xml에 라이브러리 추가

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 다중 파일 업로드 -->
        <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

 

2. servlet-context.xml에 multipartResolver 이름으로 빈 등록

 

  • CommonsMultipartResolver 클래스 property
property type 설명
maxUploadSize long 최대 업로드 가능한 파일 크기 설정
maxInMemorySize int 디스크에 임시 파일을 생성하기 전 메모리에 보관할 수 있는 최대 바이트 크기
defaultEncoding String 인코딩 설정
1
2
3
4
5
6
<!-- multipartResolver 빈 설정 -->
    <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <beans:property name="maxUploadSize" value="52428800"/>        <!-- 최대 업로드가 가능한 파일 크기 설정 -->
        <beans:property name="maxInMemorySize" value="1000000"/>    <!-- 디스크에 임시 파일을 생성하기 전 메모리에 보관할 수 있는 최대 -->
        <beans:property name="defaultEncoding" value="utf-8" />
    </beans:bean>
cs

 

3-1. 자바 파일 작성 - FileDownloadController.java

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
37
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
import net.coobird.thumbnailator.Thumbnails;
 
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
 
@Controller
public class FileDownloadController {
    private static String CURR_IMAGE_REPO_PATH = "C:\\workspace-spring\\imageRepo";
 
    @RequestMapping("/download")
    protected void download(@RequestParam("imageFileName"String imageFileName, HttpServletResponse response) throws  Exception{
        OutputStream out =response.getOutputStream();
        String downFile = CURR_IMAGE_REPO_PATH + "\\" + imageFileName;
        //다운로드될 파일 객체 생성
        File file = new File(downFile);
 
        response.setHeader("Cache-Control""no-cache");
        //헤더에 파일 이름을 설정함
        response.addHeader("Content-disposition""attachment; fileName=" + imageFileName);
 
        FileInputStream in = new FileInputStream(file);
        byte[] buffer = new byte[1024*8];
        //버퍼를 이용해 한번에 8kbyte씩 브라우저로 전송함
        while (true){
            int count = in.read(buffer);
            if(count == -1break;
            out.write(buffer, 0, count);
        }
        in.close();
        out.close();
    }
cs

 

3-2. 자바 파일 작성 - FileUploadController.java

 

  • MultipartHttpServletRequest 인터페이스 이용 : HttpServletRequest , MultipartRequest 인터페이스 상속받음.
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import org.springframework.stereotype.Controller;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
 
@Controller
public class FileUploadController {
 
    //파일 저장 위치 지정
    private static final String CURR_IMAGE_REPO_PATH = "C:\\workspace-spring\\imageRepo";
 
    @RequestMapping(value = "/form")        //업로드 페이지인 uploadForm.jsp 반환
    public String form(){
        return "uploadForm";
    }
    @RequestMapping(value = "/upload" , method = RequestMethod.POST)
    public ModelAndView upload(MultipartHttpServletRequest multipartRequest, HttpServletResponse response) throws Exception{
        multipartRequest.setCharacterEncoding("utf-8");
 
        Map map = new HashMap();    //매개변수 정보와 파일 정보를 저장할 Map 생성
        Enumeration enu = multipartRequest.getParameterNames();
        
        //전송된 매개변수 값을 key/value로 map에 저장함.
        while (enu.hasMoreElements()){
            String name = (String) enu.nextElement();
            String value = multipartRequest.getParameter(name);
            
            map.put(name, value);
        }
        //파일을 업로드한 후 반환된 파일 이름이 저장된 fileList
        List fileList = fileProcess(multipartRequest);
        map.put("fileList", fileList);
 
        ModelAndView mav = new ModelAndView();
 
        //map을 결과창으로 포워딩
        mav.addObject("map",map);
        mav.setViewName("result");
       return mav;
    }
 
    private List<String> fileProcess(MultipartHttpServletRequest multipartRequest) throws Exception{
        List<String> fileList = new ArrayList<String>();
 
        //첨부된 파일 이름을 가져옴
        Iterator<String> fileNames = multipartRequest.getFileNames();
        while (fileNames.hasNext()){
            String fileName = fileNames.next();
            //파일 이름에 대한 MultipartFile 객체를 가져옴
            MultipartFile mFile = multipartRequest.getFile(fileName);
            //실제 파일 이름을 가져옴
            String originalFilename = mFile.getOriginalFilename();
            //파일 이름 하나씩 fileList에 저장함
            fileList.add(originalFilename);
 
            File file = new File(CURR_IMAGE_REPO_PATH + "\\" + fileName);
            //경로에 파일이 없다면 그 경로에 해당하는 디렉토리를 만든 후 파일 생성함
            if(mFile.getSize() != 0) {      //file null check
                if (! file.exists()) {
                    if (file.getParentFile().mkdirs()) {
                        file.createNewFile();
                    }
                }
                //임시로 저장된 multipartFile을 실제 파일로 저장
                mFile.transferTo(new File(CURR_IMAGE_REPO_PATH + "\\" +originalFilename));
            }
        }
 
        return fileList;        //첨부한 파일 이름이 저장된 fileList 반환
    }
}
cs

 

4-1. JSP 파일 작성 - uploadForm.jsp

 

  • 파일 업로드 시에는 반드시 form 태그에 enctype = multipart/form-data , method = post 설정 필요(에러 주의....)
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
37
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<c:set var="contextPath"  value="${pageContext.servletContext.contextPath}"  />
<%
    request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>파일 업로드</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript">
        var cnt = 1;        //파일 업로드 name값을 다르게 하는 변수임
        //파일 추가를 클릭하면 동적으로 파일 업로드를 추가함.
        //name 속성 값으로 file+cnt를 설정함 => 값이 다르게 설정됨
        function fn_addFile() {
            $("#d_file").append("<br>" + "<input type='file' name='file"+cnt+"' />");
        }
 
    </script>
</head>
<body>
<h1>파일 업로드하기</h1>                            <!-- 파일 업로드 시 반드시 필요한 enctype 설정 -->
<form action="${contextPath }/upload" method="post" enctype="multipart/form-data">
    <label>아이디 : </label>
    <input type="text" name="id"><br>    <!-- 텍스트 박스에 ID를 입력받아 전송 -->
    <label>이름 : </label>
    <input type="text" name="name">        <!-- 텍스트 박스에 이름을 입력받아 전송 -->
                                        <!-- 파일 추가를 클릭하면 동적으로 파일 업로드를 추가함-->
    <input type="button" value="파일 추가" onclick="fn_addFile()"><br>
    <div id="d_file">       <!--자바스크립트를 이용해 div 태그 안에 파일 업로드를 추가함.-->
    </div>
    <input type="submit" value="업로드">
</form>
</body>
</html>
cs

 

4-2. JSP 파일 작성 - result.jsp

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
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<c:set var="contextPath"  value="${pageContext.servletContext.contextPath}"  />
<%
    request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>결과</title>
</head>
<body>
    <h1>업로드가 완료되었습니다.</h1>
    <label>아이디 : </label>
    <input type="text" name="id" value="${map.id}" readonly><br> <!-- map으로 넘어온 매개변수 값 표시 -->
 
    <label>이름 : </label>
    <input type="text" name="name" value="${map.name}" readonly><br>  <!-- map으로 넘어온 매개변수 값 표시 -->
 
    <div>
        <c:forEach var="imageFileName" items="${map.fileList}">
            <img src="${contextPath}/download?imageFileName=${imageFileName}" alt="이미지">
            <br><br><br>
        </c:forEach>
    </div>
    <p>
        <a href='${contextPath }/form'> 다시 업로드</a> </p>
    </p>
</body>
</html>
cs

 

5. 실행 화면

 

  • FileUploadController.java 에 매핑해둔 /form로 요청하면 uploadForm.jsp로 이동

 

연습2. 썸네일 이미지 이용 (상품 목록 나열시 빠르게 표시할 수 있음.)

 

1. pom.xml에 썸네일 라이브러리 추가

1
2
3
4
5
6
<!-- 썸네일 이미지 -->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.16</version>
        </dependency>
cs

 

2. FileDownloadController.java 추가

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
 @RequestMapping("/downloadT")
    protected void downloadT(@RequestParam("imageFileName"String imageFileName, HttpServletResponse response) throws  Exception{
        OutputStream out = response.getOutputStream();
        
        String downFile = CURR_IMAGE_REPO_PATH + "\\" + imageFileName;
        File image = new File(downFile);
        
        //확장자를 제외한 원본 이미지 파일의 이름을 가져옴
        //.jpg나 .png 이런 식이니까 .이전의 이름 가져오기
        int lastIndex = imageFileName.lastIndexOf(".");
        String fileName = imageFileName.substring(0, lastIndex);
        File thumbnail = new File(CURR_IMAGE_REPO_PATH + "\\" + "thumbnail" + "\\" +fileName + ".png");
        
        //원본 이미지 파일을 가로세로 50픽셀인 png 형식으로 재생성한다.
        if(image.exists()) {
            thumbnail.getParentFile().mkdir();
            Thumbnails.of(image).size(5050).outputFormat("png").toFile(thumbnail);
        }
        
        //생성된 썸네일 파일을 브라우저로 전송
        FileInputStream in = new FileInputStream(thumbnail);
        byte[] buffer = new byte[1024 * 8];
        //버퍼를 이용해 한번에 8kbyte씩 브라우저로 전송함
        while(true) {
            int cnt = in.read(buffer);
            if(cnt == -1) {
                break;
            }
            out.write(buffer, 0, cnt);
        }
        in.close();
        out.close();
        
    }
cs
반응형
profile

my code archive

@얼레벌레 개발자👩‍💻

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

반응형