JSP 파일 업로드 해보기

2025. 2. 28. 10:17·Server/JSP - TomCat - Servlet

파일 업로드 하기

 

 

파일 다운로드 받기

 

 

다운로드 받은 파일

 

 

⭐️ JSP에서 파일 업로드 하고 다운 받기

 

[ boardEnrollForm.jsp - form 태그 부분 ]

<form action="${pageContext.request.contextPath}/insert.bo" method="post" enctype="multipart/form-data">
    <table border="1" align="center" class="list-area">
        <tr>
            <th width="70">카테고리</th>
            <td width="500">
                <select name ="category">
                    <c:forEach var="c" items="${categories}">
                      <option value="${c.categoryNo}">${c.categoryName}</option>
                    </c:forEach>
                </select>
            </td>
        </tr>
        <tr>
            <th>제목</th>
            <td>
                <input type="text" name="title" required/>
            </td>
        </tr>
        <tr>
          <th>내용</th>
          <td>
              <textarea name="content"  rows="10" style="resize: none"></textarea>
          </td>
        </tr>
        <tr>
          <th>첨부파일</th>
          <td>
            <input type="file" name="upfile"/>
          </td>
        </tr>
    </table>

    <br>

    <div align="center">
        <button type="submit">작성하기</button>
        <button type="reset">취소하기</button>
    </div>
</form>

 

우선 파일을 업로드하기 위해선 enectype(인코딩 방식)을 multipart/form-data로 보내줘야 한다.

 

✨ 속성값 설명

application/x-www-form-urlencoded   기본값으로, 모든 문자들은 서버로 보내기 전에 인코딩됨을 명시함.
multipart/form-data   모든 문자를 인코딩하지 않음을 명시함.
이 방식은 <form> 요소가 파일이나 이미지를 서버로 전송할 때 주로 사용함.
text/plain   공백 문자(space)는 "+" 기호로 변환하지만, 나머지 문자는 모두 인코딩되지
않음을 명시함.

 

 

[ 파일 업로드시 필요 라이브러리 ]

commons-fileupload2-core-2.0.0-M2.jar
commons-fileupload2-jakarta-2.0.0-M1.jar
commons-io-2.16.1.jar 라이브러리를 사용하겠다.

commons-fileupload2-core : 주요기능을 구현하는 라이브러리(멀티파트 요청에 대한 처리기능)
commons-fileupload2-jakarta : javax.servlet -> jakarta.servlet 패키지를 사용하게 하는 라이브러리
commons-io : 파일 읽기/쓰기에 대한 스트림(입출력기능)을 구현하고 있는 라이브러리

 

 

[ BoardInsertController.java ]

 if(JakartaServletFileUpload.isMultipartContent(request)) { //enctype이 multipart/form-data로 전송이 되었는지 (true/false)
    HttpSession session = request.getSession();

    //1. 파일용량제한(byte)
    int fileMaxSize = 1024 * 1024 * 50; //50MB
    int requestMaxSize = 1024 * 1024 * 60; //전체요청 크기제한

    //2.전달된 파일을 저장시킬 폴더 경로 가져오기
    String savePath = request.getServletContext().getRealPath("/resources/board-upfile/");

    //3. DiskFileItemFactory(파일을 임시로 저장) 객체 생성
    DiskFileItemFactory factory = DiskFileItemFactory.builder().get();

    //JakartaServletFileUpload http요청으로 들어온 파일데이터 파싱 -> 개별 FileItem 객체로 변환
    JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);

    upload.setFileSizeMax(fileMaxSize);
    upload.setSizeMax(requestMaxSize);

    //요청(request)로부터 파일아이템(요청정보) 파싱
    List<FileItem> formItems = upload.parseRequest(request);

    Board b = new Board();
    Attachment at = null;

    //로그인 정보가져오기
    Member m = (Member)session.getAttribute("loginUser");
    b.setBoardWriter(m.getUserNo());

    for(FileItem item : formItems) {
        System.out.println(item);
        //업로드된 데이터가 일반 폼 필드인지, 파일인지를 구분할 수 있음
        if(item.isFormField()) { //일반파라미터
            switch(item.getFieldName()) {
                case "category":
                    int categryNo = Integer.parseInt(item.getString(Charset.forName("UTF-8")));
                    b.setCategoryNo(categryNo);
                    break;
                case "title":
                    b.setBoardTitle(item.getString(Charset.forName("UTF-8")));
                    break;
                case "content":
                    b.setBoardContent(item.getString(Charset.forName("UTF-8")));
                    break;
            }
        } else {//파일
            String originName = item.getName();

            if(originName.length() > 0) { //파일업로드를 했을 때 취소시 공백으로 넘어 갈 수 있으므로 0이상 처리
                //파일명이 겹치면 덮어씌우기 때문에 고유한 파일명 만듬
                String tmpName = "kh_" + System.currentTimeMillis() + ((int)(Math.random() * 100000) + 1);
                String type = originName.substring(originName.lastIndexOf("."));
                String changeName = tmpName + type; //서버에 저장할 파일명

                File f = new File(savePath, changeName);
                item.write(f.toPath()); //지정한 경로에 파일 업로드

                at = new Attachment();
                at.setOriginName(originName);
                at.setChangeName(changeName);
                at.setFilePath("resources/board-upfile/");
            }
        }
    }

    //저장정보를 request객체에서 가져온 상태
    System.out.println(b);
    System.out.println(at);

    // service 호출
    int result = new BoardService().insertBoard(b, at);

    if(result > 0) { //성공
        request.getSession().setAttribute("alertMsg", "일반게시글 작성 성공");
        response.sendRedirect(request.getContextPath() + "/list.bo?cpage=1");
    } else {
        if(at != null) {
            new File(savePath + at.getChangeName()).delete();
        }

        request.setAttribute("errorMsg", "게시글 작성 실패.");
        request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
    }
}

 

1️⃣

Controller에서는 파일 업로드를 위한 라이브러리를 받아주고, 

JakartaServletFileUpload.isMuultipartContent(request)를 이용하여 요청 타입이

multipart/form-data인지 확인한다.

 

2️⃣

파일 용량을 제한해야하기때문에 파일 용량을 제한시키고, 넘어온 파일 데이터를 파싱하기 위해서

DiskFileItemFactory 객체 생성 , JakartaServletFileUpload 객체를 생성

이때 개별 FileItem 객체로 변환이됨.

FilItem 객체를 요청(request)로 부터 파일아이템(요청정보) 파싱한다.

 

3️⃣

Board 객체(일반 파라미터)와 Attachment 객체(파일) 객체 생성 후,

로그인 정보를 세션에서 가져와 게시물을 insert할때 어느 유저가 등록한지 알 수 있게 만들어준다.

-> 데이터 베이스에 WHERE USER_ID = ? 로 넣어야하기 때문

 

4️⃣

그다음 반복문으로 FileItem이 일반 폼 필드(일반 파라미터)인지 파일인지 구별해서

값을 분리 시켜준다.

 

일반 파라미터는 getFieldName()으로 가져와서 값을 int로 파싱

-> (서버로 넘어온 데이터는 String으로 넘어오기 때문)

 

파싱 후 Board 객체에 넣어주고, 파일 객체는 getName()으로 받아준다.

 

파일 업로드시 공백으로 업로드되는걸 방지해주고, 이름이 겹칠 수 있기때문에 파일 이름을

겹칠 수 없도록 만들어준다.

 

그다음 Attachment객체에 값을 넣어준다.

 

5️⃣

Board 객체와 Attachment객체를 이용해서 Service <-> Dao <-> DB로 값을 넘겨줘서

Insert 하면 파일을 등록할 수 있다.

 


 

[ boardDetailView.jsp - 첨부파일 띄우기 ]

<th>첨부파일</th>
    <td colspan="3">
    <c:choose>
        <c:when test="${empty attachment}">
            첨부파일이 없습니다.
        </c:when>
        <c:otherwise>
            <a download="${attachment.originName}"
               href="${pageContext.request.contextPath}/${attachment.filePath}${attachment.changeName}">
                    ${attachment.originName}
            </a>
        </c:otherwise>
    </c:choose>
</td>

 

JSTL core 태그와 EL구문을 통해 View에서 첨부파일이 있는경우와 없는경우를

Choose , when, otherwise로 분리시켜 놓았다.

 

'Server > JSP - TomCat - Servlet' 카테고리의 다른 글

JSP 포워딩(Forwarding)과 리다이렉트(Redirect)의 차이  (1) 2025.02.27
session.removeAttribute()와 session.invalidate() 차이  (2) 2025.02.26
JSTL에 대하여  (2) 2025.02.24
JSP Scope에 대하여  (0) 2025.02.23
Servlet에대하여  (0) 2025.02.21
'Server/JSP - TomCat - Servlet' 카테고리의 다른 글
  • JSP 포워딩(Forwarding)과 리다이렉트(Redirect)의 차이
  • session.removeAttribute()와 session.invalidate() 차이
  • JSTL에 대하여
  • JSP Scope에 대하여
KoesJin
KoesJin
hEELo
  • KoesJin
    Seok DevLog
    KoesJin
  • 전체
    오늘
    어제
    • 분류 전체보기 (109)
      • Back End (31)
        • DataBase (15)
        • JAVA (12)
        • JDBC (4)
      • Front End (9)
        • HTML5 & CSS (3)
        • Java Script (6)
        • REACT (0)
      • Server (9)
        • JSP - TomCat - Servlet (7)
        • Spring Boot (2)
      • GitHub (1)
      • IT 지식 (기술면접 대비) (20)
      • Weekly TIL (39)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    순서에 대하여
    weekly til - day 41
    GC
    weekly til - day 43
    where
    INNER JOIN
    select
    MVC 패턴
    weekly til - day 39
    DAO
    order by
    exception
    css
    weekly til - day 38
    from
    View
    DDL
    dml
    weekly til - day 40
    commit
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
KoesJin
JSP 파일 업로드 해보기
상단으로

티스토리툴바