JSP + Servlet | 파일 업로드

파과·2022년 7월 21일
0

JSP + Servlet

목록 보기
24/33

📩 파일 업로드 COS 라이브러리 사용하기

자바에서 파일을 업로드하기 위해서는 COS 라이브러리가 제일 많이 사용되고 있다. 참고로 COS는 com.oreilly.servlet의 약자이다. (tmi: O'reilly는 프로그래밍 책 출판으로 유명한 출판사 이름이자 CEO 이름.)

COS 라이브러리 준비

http://servlets.com/cos/ 에서 Download 항목을 찾아 다운받는다.
lib폴더의 cos.jar파일을 새로 생성한 Dynamic Web Project의 WEB-INF\lib폴더에 복사한다.

form에서 파일 전송하기

폼 태그의 속성을
method="post",
enctype="multipart/form-data"
로 추가한다.

  • get방식은 주소창을 타고 넘어가기 때문에 255자 이하의 데이터만 전송할 수 있다. 따라서 파일과 같은 데이터는 post방식을 사용한다.

  • enctype 속성(인코딩 타입을 지정하는 속성)을 추가하지 않으면 파일 이름만 전송되고 파일 객체가 전송되지 않는다. 파일(이미지)이 전송된다고 알려주는 속성이라고 생각하면 된다.
    참고 : 🔗 enctype이란?

  • type="file"로 지정한 input 태그를 form 태그 안에 추가해 파일 선택 버튼을 만들 수 있다.

  • 파일 전송을 위해서는 type="submit"인 input 태그를 이용한다.


upload.jsp

<%@ 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>
</head>
<body>
	<form action="upload.do" method="post" enctype="multipart/form-data">
	글쓴이: <input type="text" name="name"><br>&nbsp;: <input type="text" name="title"><br>
	파일 지정하기: <input type="file" name="uploadFile"><br>
	<input type="submit" value="전송">
	</form>
</body>
</html>

여기까지 입력하고 실행하면 파일 선택 버튼이 생성되고 전송할 파일을 선택할 수 있다.


MultipartRequest

실제 파일 전송을 위해서는 cos.jar파일에서 제공하는 MultipartRequest 클래스를 사용한다.
다음은 MultipartRequest의 생성자로, 생성되는 순간 파일이 전송되어 서버에 저장된다.

MultipartRequest(
	javax.servlet.http.HttpServletRequest request,
    java.lang.String saveDirectory,
    int maxPostSize,
    java.lang.String encoding,
    FileRenamePolicy policy
)
  • request는 MultipartRequest와 연결할 request 객체.
  • saveDirectory는 서버 측에 저장될 경로.
  • maxPostSize는 최대 파일 크기.
  • encoding은 파일 인코딩 방식 (파일명이 한글일 경우 매개변수 값을 utf-8로 준다)
  • policy는 파일 중복 처리를 위한 매개 변수. 같은 파일이 올라갈 경우 자동으로 뒤에 숫자를 붙여준다. 매개변수 값으로는 new DefaultFileRenamePolicy()를 사용한다.

다음은 입력폼에서 선택한 파일을 실제로 업로드하는 서블릿 클래스다.

UploadServlet.java

package com.saeyan.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

@WebServlet("/upload.do")
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		// 여기를 바꿔주면 다운받는 경로가 바뀜
		String savePath = "upload";
		// 최대 업로드 파일 크기 5MB로 제한
		int uploadFileSizeLimit = 5 * 1024 * 1024;
		String encType = "UTF-8";
		ServletContext context = getServletContext();
		String uploadFilePath = context.getRealPath(savePath);
		System.out.println("서버상의 실제 디렉토리 :");
		System.out.println(uploadFilePath);
		try {
			MultipartRequest multi = new MultipartRequest(request, // request 객체
					uploadFilePath, // 서버상의 실제 디렉토리
					uploadFileSizeLimit, // 최대 업로드 파일 크기
					encType, // 인코딩 방법
					// 동일한 이름이 존재하면 새로운 이름이 부여됨
					new DefaultFileRenamePolicy());
			// 업로드된 파일의 이름 얻기
			String fileName = multi.getFilesystemName("uploadFile");
			if (fileName == null) { // 파일이 업로드 되지 않았을때
				System.out.print("파일 업로드 되지 않았음");
			} else { // 파일이 업로드 되었을때
				out.println("<br> 글쓴이 : " + multi.getParameter("name"));
				out.println("<br> 제 &nbsp; 목 : " + multi.getParameter("title"));
				out.println("<br> 파일명 : " + fileName);
			}// else
		} catch (Exception e) {
			System.out.print("예외 발생 : " + e);
		}// catch
	}

}

코드 설명

  • MultipartRequest와, 파일 업로드시 중복 처리를 위한 DefaultFileRenamePolicy 클래스를 import한다.

  • 파일은 savePath로 저장한 upload 폴더에 저장된다 (WebContent에 upload란 이름의 폴더 하나 만들자). 다음 코드로는 서버상에 파일이 저장되는 실제 경로를 찾아낸다.

ServletContext context = getServletContext();
String uploadFilePath = context.getRealPath(savePath);
  • 실제 파일은 .metadata 디렉토리에 생성되는 워크스페이스 내에 저장된다.
    C:\work\jspworkspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
    실행 후 이 폴더에 실제로 저장이 됐는지 확인.
  • MultipartRequest 객체에는 다음과 같이 값을 주어 생성한다. 객체가 생성되는 순간 파일은 이미 전송되어 서버에 저장된다.
    MultipartRequest multi = new MultipartRequest(
		request, // request 객체
		uploadFilePath, // 서버상의 실제 디렉토리
		uploadFileSizeLimit, // 최대 업로드 파일 크기
		encType, // 인코딩 방법	
        new DefaultFileRenamePolicy() // 동일한 이름이 존재하면 새로운 이름이 부여됨
	);
  • 파일 업로드와 관련한 요청 처리를 위해서는 MultipartRequest 클래스의 메소드를 사용해야 한다. 폼에서 전송된 파라미터의 이름을 얻기 위해서는 Request.getParameter()를 사용할 수 없고 MultipartRequest.getParameter()를 사용한다.

  • 선택한 파일 이름을 얻어오려면 input태그의 name 속성 값을 getFilesystemName()의 매개변수로 전달해준다. 업로드한 이름이 아니라 원래 파일명을 알고 싶으면 getOriginalFileName()을 사용한다.

0개의 댓글