본문 바로가기

프로그래밍/JSP 프로그래밍

JSP 프로그래밍_JSP에서 파일 업로드 하기

JSP에서 파일 업로드하기

1. form 화면에 데이터 타입을 form의 MIME TYPE을 enctype="multipart/form-data"로 선언해야 한다.
2. 서블릿에 @MultipartConfig 어노테이션을 선언해야 한다.
→ 자바 서블릿에서 지원하는 어노테이션으로 별도의 외부 라이브러리를 사용하지 않아도 파일을 업로드할 수 있다.
→ HttpServletRequest 인터페이스에서 제공하는 getPart() 메서드를 사용해 파일 업로드 된 내용을 가져올 수 있다.

 

home.jsp 파일 - form 태그로 화면 구현

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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<script
    src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.slim.min.js"></script>
<script
    src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script
    src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <!-- <div class="d-flex w-50 h-50 justify-content-*-center flex-column"> -->
    <div class="d-flex m-3">
        <!-- 경로 찾을 때 : path기반 -> URI 형식 기준으로 사용하자. (상대 경로, 절대 경로) -->
        <form action="upload" method="post" enctype="multipart/form-data">
            <div class="custom-file mb-3">
                <input type="file" class="custom-file-input" id="customFile" name="file"> 
                <label class="custom-file-label" for="customFile">Choose file</label>
            </div>
 
            <div class="mt-3">
                <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </form>
 
    </div>
    
    <script>
    // $ - 제이쿼리에 시작 / "change"라는 이벤트 발생
    $(".custom-file-input").on("change"function() {
        // 앞에 파일 이름 split("\\")으로 지움
          let fileName = $(this).val().split("\\").pop();
 
       $(this).siblings(".custom-file-label").addClass("selected").html(fileName);
    });
    </script>
</body>
</html>
cs

→ 파일을 업로드 하기 위해서는 form태그에 enctype="multipart/form-data"를 반드시 적어주어야 한다.

그리고 input태그 name 속성을 'file'로 하여 써블릿 파일에서 request.getPart("file")로 사용해 요청할 수 있도록 한다.

 

UploadController.java - 서블릿에 @MultipartConfig 어노테이션을 선언하기.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.tenco.controller;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
 
@WebServlet("/upload")
@MultipartConfig // 선언하기
public class UploadController extends HttpServlet {
    private static final long serialVersionUID = 1L;
 
    public UploadController() {
        super();
    }
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }
 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        // 파일 업로드 처리
        // .getPart("name속성")
        Part filePart = request.getPart("file");
        System.out.println("컨텐츠 확인 : " + filePart.getContentType()); // 컨텐츠 확인 : image/png
        System.out.println("바이트 기준 : " + filePart.getSize()); // 바이트 기준 : 420284
        System.out.println("파일 이름 : " + filePart.getSubmittedFileName()); // 파일 이름 : Screenshot_21.png
 
        // 스트림 준비 filePart에 스트림을 연결하기
        InputStream fileContent = filePart.getInputStream();
 
        // 출력 스트림 준비 (우리 서버 컴퓨터에 출력할 예정)
        OutputStream outputStream = null;
 
        try {
            // 사용자 파일명 중복 방지
            UUID uuid = UUID.randomUUID();
            // db에서 구분하기 위해
            // 서버에서 저장되는 파일 이름 : uuid + "_" + filePart.getSubmittedFileName();
            // 원본 파일 이름 : filePart.getSubmittedFileName();
            String fileName = uuid + "_" + filePart.getSubmittedFileName();
 
            // 폴더를 코드상으로 직접 생성해보기 : 2단계
            String saveDirectory = "C:/demo12";
            File dir = new File(saveDirectory);
 
            // 파일이 있으면 true, 없으면 flase
            if (!dir.exists()) {
                dir.mkdirs();
            }
 
            // 미리 폴더를 만들어두자. : 1단계
            File file = new File("C:/demo12/", fileName);
 
            // 출력 스트림 사용
            outputStream = new FileOutputStream(file);
 
            // 빨리 읽어오기 위해
            byte[] buffer = new byte[1024];
            int length;
 
            // 한 번에 1024바이트 만큼 받아서 length에 담음.
            // fileContent.read(buffer) <- inputStream 읽음.
            while ((length = fileContent.read(buffer)) != -1) {
                // 1024 크기 바이트 읽었음.
                // 0번째부터 length까지 읽어라.
                outputStream.write(buffer, 0length);
            }
            // 파일 생성 완료!
            System.out.println("파일 생성 완료");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            fileContent.close();
            if (outputStream != null) {
                outputStream.flush();
                outputStream.close();
            }
            
            response.sendRedirect("/demo12/home.jsp");
        }
        
    }
 
}
 
cs

→ @MultipartConfig 어노테이션을 선언하여 getPart() 메서드로 파일 업로드된 내용을 가져올 수 있다.

→ 입력스트림과 출력스트림을 생성하고 UUID를 생성해 사용자가 파일명을 중복하지 않도록 방지한다. 

→ File클래스를 이용해 미리 폴더를 만들고 반복문을 이용해 출력 스트림으로 뽑아내면 된다.

 

 

파일 만들기 

1
2
3
4
5
6
7
8
// 폴더를 코드상으로 직접 생성해보기 : 2 단계
String saveDirectory = "c:/demo12";
File dir = new File(saveDirectory);
 
// 파일이 있으면 true, 없으면 false
if(!dir.exists()) {
    dir.mkdirs();
}
cs

→ 위 코드에 이 내용을 추가하면 C드라이버에 demo12 폴더가 생성이 되고 jsp파일에서 이미지가 들어가게 된다.