반응형
# Spring WEB MVC_02버전_05 다중 파일 업로드 구현_UI 구현
## pom.mxl
- Spring에서 파일 업로드, 다운로드 위한 API 설정.
- mvnRepository 에서 commons-fileupload / commons io 찾아서 pom.xml에 dependency 등록
- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload
- https://mvnrepository.com/artifact/commons-io/commons-io
## servlet-context.xml
- 다중 업로드 하기위한 API beans 설정
<!-- 다중 업로드 API -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/> // 업로드 가능한 최대 파일 크기
<beans:property name="maxInMemorySize" value="100000"/> // 업로드 전 메모리에 보관할 수 있는 최대 byte 크기
<beans:property name="defaultEncoding" value="utf-8"/> // 인코딩
</beans:bean>
## uploadForm 생성
- 프로젝트 > src > webapp > WEB-INF > views 우 클릭 > New > JSP File > uploadForm.jsp 이름으로 생성
- 부트스트랩(https://www.w3schools.com/bootstrap/bootstrap_panels.asp) > BS Panels > Panel Heading 사용
- panel-body에 사용할 폼도 부트스트랩 이용(https://www.w3schools.com/bootstrap/bootstrap_forms.asp) > Bootstrap Horizontal Form 사용
- 파일 추가 버튼 클릭 시마다 파일 추가할 수 있는 input 생성되도록 작업.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
<script>
var cnt = 1;
function file_add() {
$("#d_file").append("<br>" + "<input type='file' name='file" + cnt + "'/>");
cnt++;
}
</script>
</head>
<body>
<div class="container">
<h2>다중파일 업로드</h2>
<div class="panel panel-default">
<div class="panel-heading">스프링을 이용한 다중 파일 업로드 구현</div>
<div class="panel-body">
<form class="form-horizontal" action="<c:url value='/upload.do'/>" enctype="multipart/form-data" method="post">
<div class="form-group">
<label class="control-label col-sm-2" for="id">아이디:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="id" placeholder="Enter id" style="width: 30%;">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="name">이름:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" placeholder="Enter name" style="width: 30%;">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="">파일추가:</label>
<div class="col-sm-10">
<input type="button" value="파일추가" onClick="file_add()"/><br>
<div id="d_file"></div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">업로드</button>
</div>
</div>
</form>
</div>
<div class="panel-footer">다중파일 업로드JSP</div>
</div>
</div>
</body>
</html>
## MemberController
@RequestMapping("/form.do")
public String form() {
return "uploadForm";
}
# Spring WEB MVC_02버전_06~07 다중 파일 업로드 구현_서버쪽 구현
## FileController 생성
- 파일 업로드, 다운로드 할 수 있는 컨트롤러
- 프로젝트 > Java Resources > src/main/java > kr.narp.myapp1 우 클릭 > New > Class > FileController 이름으로 생성
- Enumberation<String> : 나열, 열거형. 데이터가 있으면 가져오고 없으면 반복문을 멈춘다. (데이터의 유무 판단해서 가져옴)
- getParameterNames : id, name 등만 읽어 들임.
- getFileNames : 파일 이름이 아닌, 파라미터 이름을 읽어 들임.(file1, file2 ..)
- Iterator : 나열, 열거형, Enumberation과 비슷하나 속도 측면에서 조금 더 빠름.
- MultipartFile : 스프링에서 제공해주는 첨부파일을 담을 수 있는 클래스, 하나의 파일을 받을 때 사용(파일의 크기, 파일의 이름, 파일의 타입 등..)
- getOriginalFilename : 실제 업로드 된 파일의 이름을 담고 있다.
- 파일 업로드 경로 : C:\eGovFrame-3.9.0\workspace.edu\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringMVC02
package kr.narp.myapp1;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@Controller
public class FileController {
@RequestMapping("/upload.do")
public String upload(MultipartHttpServletRequest multipartRequest,
HttpServletRequest request, Model model) throws Exception {
String UPLOAD_DIR = "repo";
// UPLOAD_DIR의 실제 경로 가져오는 것.
String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
// 1. id, name 파라미터 읽어오기
Map map = new HashMap(); // (KEY, Value)
// String id = multipartRequest.getParameter("id");
// String name = multipartRequest.getParameter("name");
Enumeration<String> e = multipartRequest.getParameterNames();
while (e.hasMoreElements()) {
String name = e.nextElement(); // id
String value = multipartRequest.getParameter(name);
map.put(name, value);
}
// 2. 파일 담고있는 파라미터 읽어오기
Iterator<String> it = multipartRequest.getFileNames();
List<String> fileList = new ArrayList<String>();
while (it.hasNext()) {
String paramfName = it.next();
MultipartFile mFile = multipartRequest.getFile(paramfName);
String oName = mFile.getOriginalFilename(); // 실제 업로드된 파일 이름
fileList.add(oName);
// 파일 업로드할 경로 확인
File file = new File(uploadPath + "\\" + paramfName);
if (mFile.getSize() != 0) {
if (!file.exists()) {
if (file.getParentFile().mkdirs()) {
file.createNewFile(); // 임시로 파일을 생성한다.
}
}
mFile.transferTo(new File(uploadPath + "\\" + oName)); // 파일 업로드
}
}
map.put("fileList", fileList);
model.addAttribute("map", map);
return "result";
}
}
## pom.xml
- Servlet 버전 변경
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
## result.jsp 생성
- 프로젝트 > src > main > webapp > WEB-INF > views 우 클릭 > New > JSP File > result.jsp 생성
- 부트스트랩 사용 (https://www.w3schools.com/bootstrap/bootstrap_panels.asp) > BS Panels > Panel Heading
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>업로드 결과창</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
</head>
<body>
<div class="container">
<h2>업로드가 완료 되었습니다.</h2>
<div class="panel panel-default">
<div class="panel-heading">스프링을 이용한 다중 파일 업로드 구현</div>
<div class="panel-body">
<table class="table table-bordered table-hover">
<tr>
<td>아이디</td>
<td>${map.id}</td>
</tr>
<tr>
<td>이름</td>
<td>${map.name}</td>
</tr>
<c:forEach var="fName" items="${map.fileList}">
<tr>
<td>${fName}</td>
<td>다운로드</td>
</tr>
</c:forEach>
</table>
</div>
<div class="panel-footer">파일 업로드 결과 JSP</div>
</div>
</div>
</body>
</html>
# Spring WEB MVC_02버전_08 다중 파일 다운로드 구현
## result.jsp
- 다운로드 이미지 클릭 시 해당 파일 다운로드 가능하도록 작업
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>업로드 결과창</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
<script>
function getfile(filename) {
location.href="<c:url value='/download.do'/>?filename=" + filename;
}
</script>
</head>
<body>
<div class="container">
<h2>업로드가 완료 되었습니다.</h2>
<div class="panel panel-default">
<div class="panel-heading">스프링을 이용한 다중 파일 업로드 구현</div>
<div class="panel-body">
<table class="table table-bordered table-hover">
<tr>
<td>아이디</td>
<td>${map.id}</td>
</tr>
<tr>
<td>이름</td>
<td>${map.name}</td>
</tr>
<c:forEach var="fName" items="${map.fileList}">
<tr>
<td>${fName}</td>
<td><a href="javascript:getfile('${fName}')"><span class="glyphicon glyphicon-file"></span></a></td>
</tr>
</c:forEach>
</table>
</div>
<div class="panel-footer">파일 업로드 결과 JSP</div>
</div>
</div>
</body>
</html>
## FileController
- 다운로드 관련 메서드 추가.
package kr.narp.myapp1;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@Controller
public class FileController {
@RequestMapping("/upload.do")
public String upload(MultipartHttpServletRequest multipartRequest,
HttpServletRequest request, Model model) throws Exception {
String UPLOAD_DIR = "repo";
// UPLOAD_DIR의 실제 경로 가져오는 것.
String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
// 1. id, name 파라미터 읽어오기
Map map = new HashMap(); // (KEY, Value)
// String id = multipartRequest.getParameter("id");
// String name = multipartRequest.getParameter("name");
Enumeration<String> e = multipartRequest.getParameterNames();
while (e.hasMoreElements()) {
String name = e.nextElement(); // id
String value = multipartRequest.getParameter(name);
map.put(name, value);
}
// 2. 파일 담고있는 파라미터 읽어오기
Iterator<String> it = multipartRequest.getFileNames();
List<String> fileList = new ArrayList<String>();
while (it.hasNext()) {
String paramfName = it.next();
MultipartFile mFile = multipartRequest.getFile(paramfName);
String oName = mFile.getOriginalFilename(); // 실제 업로드된 파일 이름
fileList.add(oName);
// 파일 업로드할 경로 확인
File file = new File(uploadPath + "\\" + paramfName);
if (mFile.getSize() != 0) {
if (!file.exists()) {
if (file.getParentFile().mkdirs()) {
file.createNewFile(); // 임시로 파일을 생성한다.
}
}
mFile.transferTo(new File(uploadPath + "\\" + oName)); // 파일 업로드
}
}
map.put("fileList", fileList);
model.addAttribute("map", map);
return "result";
}
@RequestMapping("/download.do")
public void download(@RequestParam("filename") String filename,
HttpServletRequest request, HttpServletResponse response) throws Exception {
String UPLOAD_DIR = "repo";
String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
File file = new File(uploadPath + "\\" + filename);
// 클라이언트로부터 넘어오는 파일 이름에 한글 있는 경우 깨짐 방지.
filename = URLEncoder.encode(filename, "UTF-8");
filename = filename.replace("+", " ");
// 다운로드 준비 (서버에서 클라이언트에게 다운로드 준비 시키는 부분_다운로드 창 띄움)
response.setContentLength((int)file.length());
response.setContentType("application/x-msdownload;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + filename + ";");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// 실제 다운로드를 하는 부분
FileInputStream in = new FileInputStream(file); // 파일 읽기 준비
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[104];
while ( true ) {
int count = in.read(buffer);
if ( count == -1 ) {
break;
}
out.write(buffer, 0, count); // 다운로드 (0% ..... 100%)
}
in.close();
out.close();
}
}
## 작동 확인
- 업로드, 다운로드 정상작동 확인
반응형