파일 첨부 기능에 대해 알아보록 하겠습니다.
웹이나 메일에서 이미지, 파일 등등을 첨부하는 경우가 있습니다.
근데 한 개만 첨부하는 것이 아니라 한 개 이상의 여러개를 첨부하는 상황이 있습니다.
그래서 오늘은 다중 파일을 업로드 하는 기능을 구현하도록 하겠습니다.
스프링의 CommonsMultipartResolver 클래스를 이용하면 다중 파일 업로드가 가능합니다.
CommonsMultipartResolver 클래스 속성
속성 | 설명 |
maxUploadSize | 최대로 업로드가 가능한 파일의 크기를 설정합니다. |
maxInMemorySize | 디스크에 임시 파일을 생성하기 전 메모리에 보관할 수 있는 최대 바이트 크기를 설정합니다. |
defaultEncoding | 전달되는 매개변수의 인코딩을 설정합니다. |
pom.xml
<!-- 파일 업로드 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
파일업로드에 필요한 라이브러리를 pom.xml에 설정
servlet-context.xml
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="52428800"/>
<beans:property name="maxInMemorySize" value="1000000"/>
<beans:property name="defaultEncoding" value="utf-8"/>
</beans:bean>
servlet-context.xml 에서 CommonsMultipartResolver 클래스를 multipartResolver 빈으로 설정
파일 업로드/ 다운로드 컨트롤러 클래스 파일 생성
FileDownloadController.java
package com.myspring.pro28.ex01;
...................
@Controller
public class FileDownloadController {
//파일 저장 위치를 지정
private static String CURR_IMAGE_REPO_PATH = "c:\\spring\\image_repo";
//다운로드할 이미 파일 이름을 전달
@RequestMapping("/download")
protected void download(@RequestParam("imageFileName") String imageFileName,
HttpServletResponse response) throws Exception{
OutputStream out = response.getOutputStream();
String downFile = CURR_IMAGE_REPO_PATH + "\\" + imageFileName;
//다운로드한 파일 객체를 생성
File file = new File(downFile);
response.setHeader("Cache-Control", "no-cache");
//헤더에 파일 이름을 설정
response.addHeader("Content-disposition", "attachment; fileName="+imageFileName);
FileInputStream in = new FileInputStream(file);
byte[] buffer = new byte[1024 * 8];
//버퍼를 이용해 한 번에 8kbyte씩 브라우저에 전송
while(true) {
int count = in.read(buffer);
if(count == -1) break;
out.write(buffer,0,count);
}
in.close();
out.close();
}
}
버퍼 기능을 이용해 브아루저로 이미지파일을 전송합니다.
FileUploadController.java
package com.myspring.pro28.ex01;
.............................
@Controller
public class FileUploadController {
private static final String CURR_IMAGE_REPO_PATH = "c:\\spring\\image_repo";
//업로드 창인 uploadForm.jsp를 반환
@RequestMapping(value="/form")
public String form() {
return "uploadForm";
}
@RequestMapping(value="/upload", method = RequestMethod.POST)
public ModelAndView upload(MultipartHttpServletRequest multipartRequest,
HttpServletResponse response) throws Exception{
multipartRequest.setCharacterEncoding("utf-8");
// 매개변수 정보와 파일 정보를 저장할 Map을 생성
Map map = new HashMap();
// 파라미터 값을 한꺼번에 받아옴
Enumeration enu = multipartRequest.getParameterNames();
while(enu.hasMoreElements()) {
String name = (String)enu.nextElement();
String value = multipartRequest.getParameter(name);
map.put(name, value);
}
List fileList = fileProcess(multipartRequest);
map.put("fileList", fileList);
ModelAndView mav = new ModelAndView();
mav.addObject("map", map);
mav.setViewName("result");
return mav;
}
private List<String> fileProcess(MultipartHttpServletRequest multipartRequest) throws Exception{
List<String> fileList = new ArrayList<String>();
// 첨부된 파일 이름을 가져옵니다.
Iterator<String> fileNames = multipartRequest.getFileNames();
while(fileNames.hasNext()) {
String fileName = fileNames.next();
//파일 이름에 대한 MultipartFile 객체를 가져옮
MultipartFile mFile = multipartRequest.getFile(fileName);
//실제 파일 이름을 가져옴
String originalFileName = mFile.getOriginalFilename();
//파일 이름을 하나씩 저장 list
fileList.add(originalFileName);
File file = new File(CURR_IMAGE_REPO_PATH + "\\" + fileName);
//첨부된 파일이 있는지 체크 합니다.
//경로에 파일이 없으면 그 경로에 해당하는 디렉터리를 만든후 파일을 생성
if(mFile.getSize() != 0) {
if(!file.exists()) {
if(file.getParentFile().mkdirs()) {
file.createNewFile();
}
}
//임시로 저장된 multipartFile을 실제 파일로 전송
mFile.transferTo(new File(CURR_IMAGE_REPO_PATH+"\\"+originalFileName));
}
}
return fileList;
}
}
파일과 파라미터를 같이 전달해야 하므로 Map을 사용합니다.
파라미터의 name과 value를 map의 key와 value로 저장합니다.
파일이름을 list에 저장한 후 다시 map에 key/value러 저장합니다.
JSP 설정
uploadForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }"/>
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
//파일 업로드 name값을 다르게 하는 변수
var cnt=1;
function fn_addFile() {
$("#d_file").append("<br>"+"<input type='file' name='file"+cnt+"'/'>");
cnt++;
}
</script>
<meta charset="UTF-8">
<title>파일 업로드 하기</title>
</head>
<body>
<h1>파일 업로드 하기</h1>
<!-- 파일 업로드 시 encType은 반드시 multipart/form-data로 설정 해야합니다. -->
<form action="${contextPath }/upload" method="post" enctype="multipart/form-data">
<label>아이디:</label>
<input type="text" name="id"><br>
<label>이름:</label>
<input type="text" name="name"><br>
<!--파일 추가를 클릭하면 동적으로 파일 업로드를 추가 -->
<input type="button" value="파일 추가" onClick="fn_addFile()"><br>
<!--자바스크립트를 이용해 <div> 태그 안에 파일 업로드를 추가 -->
<div id="d_file">
</div>
<input type="submit" value="업로드"/>
</form>
</body>
</html>
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" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>결과창</title>
</head>
<body>
<h1>업로드가 완료되었습니다.</h1>
<label>아이디:</label>
<input type="text" name="id" value="${map.id }" readonly><br>
<label>이름 :</label>
<input type="text" name="name" value="${map.name }" readonly><br>
<!--업로드한 파일들을 forEach문을 이용해 <img> 태그에 표시함 -->
<div class="result-images">
<c:forEach var="imageFileName" items="${map.fileList }">
<img src="${contextPath }/download?imageFileName=${imageFileName}">
<br><br>
</c:forEach>
</div>
<a href='${contextPath }/form'>다시 업로드 하기</a>
</body>
</html>
#마무리
다중파일 업로드 기능은 실제로 많이 쓰이는 기능입니다. 해당 기능을 응용하여 사용하시길 바랍니다.
'개발 > 스프링' 카테고리의 다른 글
22. 스프링 프레임워크 - 인터셉터[자바 웹을 다루는 기술] (0) | 2022.05.30 |
---|---|
21. 스프링 프레임 워크 - 썸네일 이미지[자바 웹을 다루는 기술] (0) | 2022.05.30 |
19. 스프링 프레임워크 - 타일즈[자바웹을 다루는 기술] (0) | 2022.05.26 |
18. 스프링 프레임워크 - log4j[자바웹을 다루는 기술] (0) | 2022.05.25 |
17. 스프링 프레임워크 - STS에서 마이바티스 적용[자바 웹을 다루는 기술] (0) | 2022.05.25 |