[23/07/17] JSP (5)

yeju·2023년 7월 17일
0

JSP

목록 보기
6/7
post-thumbnail

📖 15. JSP에서 파일 업로드/다운로드하기

📌 JSP에서 파일 업로드하기

1. 오픈 소스 라이브러리 준비

commons-fileupload-1.3.3.jar 다운로드 받기 🔗
commons-io-2.6.jar 다운로드 받기 🔗

라이브러리를 사용할 프로젝트 폴더의 webapp/WEB-INF/lib 안에 파일 넣기

2. 파일 업로드 jsp 페이지 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 업로드</title>
</head>
<body>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>

<!-- 파일 전송할 때 form의 enctype은 multipart/form-data 로 지정 -->
<form action="${contextPath}/upload.do"
method="post" enctype="multipart/form-data">
	파일1 : <input type="file" name="file1"><br>
	파일2 : <input type="file" name="file2"><br>
	매개변수1 : <input type="text" name="param1"><br>
	매개변수2 : <input type="text" name="param2"><br>
	매개변수3 : <input type="text" name="param3"><br>
	<input type="submit" value="업로드">
</form>
</body>
</html>

파일을 업로드할 때는 form 태그의 encType 속성값을 반드시 multipart/form-data 로 지정한다.

3. 업로드 처리할 서블릿 작성

앞에서 추가한 라이브러리에서 제공하는 DiskFileItemFactory , ServletFileUpload 클래스의 메서드를 사용해 파일을 업로드함

package sec01.ex01;

import java.io.File;
import java.io.IOException;
import java.util.List;

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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/upload.do")
public class FileUpload extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String encoding = "utf-8";
		request.setCharacterEncoding(encoding);
		
		// 업로드할 파일 경로 생성
		String path = "D:\\JYJ\\-images";
		// File 객체 생성자에 파일 경로를 설정하고 객체 생성하기
		File currentPath = new File(path);
		// 경로가 존재하지 않으면 새로 생성하기
		if(!currentPath.exists()) {
			try {
				currentPath.mkdir();
				System.out.println("[FileUpload] 폴더를 생성했습니다.");
			}
			catch(Exception e) {e.printStackTrace();}
		}
		else {
			System.out.println("[FileUpload] 폴더가 이미 존재합니다.");
		}
		// 파일 경로와 최대 파일 크기 설정을 위해 DiskFileItemFactory 객체 생성
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setRepository(currentPath);
		factory.setSizeThreshold(1024*1024); // 1mb
		// 설정한 내용을 매개변수로 파일을 업로드하는 ServletFileUpload 객체 생성
		ServletFileUpload upload = new ServletFileUpload(factory);
		
		try {
			// parseRequest(request) : 요청에서 넘어온 데이터를 List 타입으로 변환
			List items = upload.parseRequest(request);
			// 넘어온 데이터 목록으로 for문 실행
			for(int i=0; i<items.size(); i++) {
				// 업로드된 데이터 하나씩 가져오기
				// Object -> FileItem 타입으로 캐스팅
				FileItem fileItem = (FileItem) items.get(i);
				// 해당 데이터가 폼 필드(파일이 아닌 텍스트값)인지 확인
				if(fileItem.isFormField()) {
					// 폼 필드이면 키와 값을 콘솔에 출력
					// getFieldName() : 요청에서 넘어올 때 name(키)를 반환
					System.out.println(fileItem.getFieldName()+" : "+fileItem.getString(encoding));
				}
				// 해당 데이터가 파일이면 다음 내용 실행
				else {
                	// getName() : 저장한 파일 이름 가져오기
					String fileName = fileItem.getName();
					System.out.println("파라미터 이름 : "+fileItem.getFieldName());
					System.out.println("파일 이름 : "+fileName);
					System.out.println("파일 크기 : "+fileItem.getSize()+" bytes");
					// 지정한 경로에 파일을 업로드하기 위해 경로+파일명으로 File 객체 생성
					File uploadFile = new File(currentPath+"\\"+fileName);
                    // 지정한 경로에 파일 업로드하기
					fileItem.write(uploadFile);
				}
				// 폼 필드/파일 구별 if문 끝
			}
			// 넘어온 데이터 처리 for문 끝
		}
		catch(Exception e) {e.printStackTrace();}
	}
}

📌 JSP에서 파일 다운로드

D드라이브에 있는 파일을 jsp 페이지에 업로드해 출력, 다운로드할 수 있도록 만들기

1. 파일 다운로드를 요청할 jsp 페이지 작성

hidden 속성의 input 태그에 업로드할 파일명을 value로 넣어 출력 페이지에 전달

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 다운로드 요청하기</title>
</head>
<body>
	<form method="post" action="result.jsp">
		<input type="hidden" name="param1" value="p1234.jpg">
		<input type="hidden" name="param2" value="p1235.jpg">
		<input type="submit" value="이미지 다운로드">
	</form>
</body>
</html>

2. 내용을 출력할 jsp 페이지 작성

이전 페이지에서 받아온 파라미터를 변수 file1 , file2 로 설정하고
해당 파라미터를 /download.do 로 매핑된 서블릿에 전달해 응답받은 값을 img 태그의 src 값으로 지정

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>이미지 파일 출력하기</title>
</head>
<body>
	<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
	<c:set var="file1" value="${param.param1}"/>
	<c:set var="file2" value="${param.param2}"/>
	
	param1 :
	<c:out value="${file1}"/><br>
	<!-- 이미지 소스를 /download.do 매핑된 서블릿에서 처리해 출력 -->
	<c:if test="${not empty file1}">
		<img src="${contextPath}/download.do?fileName=${file1}" width=300 height=300><br>
	</c:if>
	<br>
	param2 :
	<c:out value="${file2}"/><br>
	<c:if test="${not empty file2}">
		<img src="${contextPath}/download.do?fileName=${file2}" width=300 height=300><br>
	</c:if>
	<br>
	파일 내려받기<br>
	<!-- 연결할 url을 /download.do 매핑된 서블릿에서 처리해 출력 -->
	<a href="${contextPath}/download.do?fileName=${file2}">파일 내려받기</a>
</body>
</html>

3. 다운로드 처리할 서블릿 작성

파일 정보를 읽어오기 위해 FileInputStream 객체가 필요하고
읽어온 파일을 출력 페이지에 전달하기 위해 OutputStream 객체가 필요함

package sec01.ex02;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

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

@WebServlet("/download.do")
public class FileDownload extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		// 파일을 가져올 경로
		String path = "D:\\JYJ\\-images";
		// 요청 url에 포함된 파라미터 가져오기
		String fileName = request.getParameter("fileName");
		System.out.println("fileName : "+fileName);
		// 응답 시 내용을 출력하기 위해 OutputStream 객체 가져오기
		OutputStream out = response.getOutputStream();
		// 다운로드할 파일 경로
		String downFile = path+"\\"+fileName;
		// 파일의 정보를 담은 File 객체 생성
		File f = new File(downFile);
		// 헤더 정보를 수정, 추가해 동작 컨트롤하기
		response.setHeader("Cache-Control", "no-cache");
		response.addHeader("Content-disposition", "attachment; fileName="+fileName);
		// 파일 정보 읽어오기 위해 FileInputStream 객체 생성
		FileInputStream in = new FileInputStream(f);
		// 데이터를 담을 메모리 공간 생성
		byte[] buffer = new byte[1024*8]; // 8kb
		while(true) {
			// 버퍼로 읽어오기, 내용이 있으면 계속 실행
			int count = in.read(buffer);
			if(count == -1) break;
			out.write(buffer,0,count);
		}
		// 다 읽어오면 스트림 닫기 
		in.close();
		out.close();
	}
}

profile
🌱

0개의 댓글