서버에는 업로드와 관련해서 다음과 같은 여러 작업이 이루어 진다.
- 사용자가 업로드 하는 시간에 따른 자동적인 폴더 생성
- 업로드 되는 파일의 고유한 이름 생성
- 이미지 파일의 업로드 시 썸네일 이미지 (웹 페이지의 작은 이미지 파일)를 생성
- 이미지 파일의 경우 서버에서 저장된 파일을 읽어서 적당한 MIME 타입으로 서비스
- 일반 파일의 경우 다둔로드 타입으로 파일 데이터 서비스
이미지 파일의 경우에는 이미지를 깨끗하게 축소할 수 있는 imgScalr 라이브러리를 활용한다.
imgScalr 라이브러리는 큰 이미지 파일을 고정된 크기로 변환할때 편리하다.
* 라이브러리 설정
http://mvnrepository.com/artifact/commons-fileupload/commons-fileupload
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Imgscalr A Java Image Scaling Library
<!-- https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib -->
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
스프링에서 multipartResolver 라고 하는 이 객체의 설정은 웹과 관련 있기 때문에 root-context.xml 이 아닌 servlet-context.xml 을
이용해서 설정한다.
servlet-context.xml
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <beans:property name="maxUploadSize" value="10485760" /> </beans:bean>
서버의 파일 저장 경로 설정
파일을 저장할 경로는 상수처럼 사용되기 때문에 servlet-context.xml 파일을 이용해서 특정 경로를 문자열로 설정한다.
1.
<!-- 서버의 파일 저장 경로 설정 --> <beans:bean id="uploadPath" class="java.lang.String"> <beans:constructor-arg value="/resources/upload" /> </beans:bean>
2. 실제 서버내 리눅스 주소를 입력 해라
<!-- 서버의 파일 저장 경로 설정 --> <beans:bean id="uploadPath" class="java.lang.String"> <beans:constructor-arg value="d:\\dev\\upload" /> </beans:bean>
FileCopyUtils 는 파일 데이터를 파일로 처리하거나, 복사하는 등의 작업에 유용하게 사용될 수 있다. FileCopyUitls 클래스의 모든 static 메소드는
copy 이고, 다음과 같은 방식들이 제공된다.
주요 static 메소드 설명
copy(byte[] in, File out ) 데이터가 담긴 바이트의 배열(in) 을 파일에 기록한다.
copy(byte[] in, OutputStream out) 데이터가 담긴 바이트의 배열(in) 을 특정한 OutputStream 으로 전송한다.
copy(InputStream in, OutputStream out) 특정한 InputStream 을 특정한 OutputStream 으로 전송한다.
copy(String in, Writer out) 문자열을 그대로 Writer 를 이용해서 기록한다.
cpyToByteArray(InputStream in) 주어진 InputStream 을 읽어서 byte[] 로 만들어 반환한다.
1. 기본적인 파일 업로드 방식
UploadController
package test.controller;
import java.io.File;
import java.util.UUID;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class UploadController {
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
@Resource(name="uploadPath")
private String uploadPath;
@RequestMapping(value="/test/uploadForm", method=RequestMethod.GET)
public void uploadForm() throws Exception{
}
@RequestMapping(value="/test/uploadForm", method=RequestMethod.POST)
public void uploadForm(MultipartFile file, Model model ) throws Exception{
logger.info("originalName : " + file.getOriginalFilename());
logger.info("size : " + file.getSize());
logger.info("contentType : " +file.getContentType());
String savedName= uploadFile(file.getOriginalFilename(), file.getBytes());
model.addAttribute("savedName", savedName);
}
private String uploadFile(String originalName, byte[] fileData) throws Exception{
UUID uid=UUID.randomUUID();
String savedName=uid.toString() + "_"+ originalName;
File target =new File(uploadPath, savedName);
FileCopyUtils.copy(fileData, target);
return savedName;
}
}
uploadForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form id="form1" action="uploadForm" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
<script type="text/javascript">
var savedName = '${savedName}';
if (savedName != '') {
alert(savedName);
location.href = "/test/uploadForm";
}
</script>
</body>
</html>
2. 기본적인 Ajax 방식의 파일 업로드

Controller
@Controller
public class UploadController {
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
@Resource(name="uploadPath")
private String uploadPath;
//실질적으로 파일 저장
private String uploadFile(String originalName, byte[] fileData) throws Exception{
UUID uid=UUID.randomUUID();
String savedName=uid.toString() + "_"+ originalName;
File target =new File(uploadPath, savedName);
FileCopyUtils.copy(fileData, target);
return savedName;
}
//Ajax 업로드용 컨트롤러와 JSP 작성하기
@RequestMapping(value="/test/uploadAjax", method=RequestMethod.GET)
public void uploadAjax(){
}
@ResponseBody
@RequestMapping(value="/test/uploadAjax", method=RequestMethod.POST,
produces="text/plain;charset=UTF-8")
public ResponseEntity<String> uploadAjax(MultipartFile file) throws Exception{
logger.info("originalName , {} ", file.getOriginalFilename());
logger.info("size : " , file.getSize());
logger.info("contentType : " + file.getContentType());
return new ResponseEntity<String>(file.getOriginalFilename(), HttpStatus.CREATED);
}
}
uploadAjax.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.fileDrop{
width:100%;
height:200px;
border:1px dotted blue;
}
small{
margin-left:3px;
font-weight:bold;
color:gray;
}
</style>
</head>
<body>
<h3>Ajax File Upload</h3>
<div class="fileDrop"></div>
<div class="uploadedList"></div>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
~~
</script>
</body>
</html>
<script>
$(".fileDrop").on("dragenter dragover", function(event){
event.preventDefault();
});
$(".fileDrop").on("drop", function(event){
event.preventDefault();
var files=event.originalEvent.dataTransfer.files;
var file=files[0];
console.log(file);
var formData=new FormData();
formData.append("file", file);
$.ajax({
url:'/test/uploadAjax',
data:formData,
dataType:'text',
processData:false,
contentType:false,
type:'POST',
success:function(data){
alert(data);
}
});
});
</script>
drop 이벤트가 발생했을 때 이벤트 처리 코드의 핵심적인 부분은 dataTransfer.files 의 부분으로, 전달된 파일 데이터를 가져오는 부분이다.
event.originalEvent 는 jQuery 를 이용하는 경우 event 가 순수한 DOM 이벤가 아니기 때문에 event.originalEvent 를 이용해서 순수한 원래의
DOM 이벤트를 가져온다.
var file=files[0];
var formData=new FormData();
formData.append("file", file);
FormData append() 를 이용해서 file 이름으로 끌어다 놓은 파일 객체를 추가하는 것을 볼 수 있다.
FormData 의 경우 HTML5에서 지원되기 시작했기 때무에 브라우저의 제약이 있는 경우가 있다.
jquery의 $.ajax() 를 이용해서 FormData 객체에 있는 파일 데이터를 전송하기 위해서는 위 코드에 나와 있는 'processData' 와
'contentType' 옵션을 반드시 false 로 지정해야만 한다. 이 두개의 옵션은 데이터 전송을 <form> 태그를 이용하여 파일 업로드와 동일하게
해주는 결정적인 역할을 한다.
processData : 데이터를 일반적인 query string 으로 변환할 것인지를 결정한다. 기본값은 true, 'application/x-www-form-urlencoded' 타입으로
전송합니다. 다른 형식으로 데이터를 보내기 위하여 자동 변환하고 싶지 않은 경우는 false 를 지정합니다.
contentType : 기본 값은 'appplication / x-www-form-urlencoded' 이다. 파일의 경우 multipart/form-data 방식으로 전송하기 위해서 false 로
지정한다.
@RequestMapping(value="/test/uploadAjax", method=RequestMethod.POST,
produces="text/plain;charset=UTF-8")
@RequestMapping 의 속성으로 produces 속성을 지정하고 있는데, 이것은 한국어를 정상적으로 전송하기 위한 간단한 설정이다.
맨 마지막의 ResponseEntitiy 를 전송하는 부분에서는 HttpStatus.CREATED 값을 지정했다. HttpStatus.CREATED 는 원하는 리소스가
정상적으로 생성되었다는 상태 토드이다. 원한다면 HttpStatus.OK 를 이용해도 무방하다.
스프링 내 파일 경로를 가져 올때
package com.macaronics.www.util.fileupload;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
public class UploadPath {
public static String attach_path ="WEB-INF/uploads/";
public static String path(HttpServletRequest request){
String uploadPath ="";
try{
String root_path =request.getServletContext().getRealPath("/");
uploadPath =root_path+attach_path.replace('/', File.separatorChar);
}catch(Exception e){
e.printStackTrace();
}
return uploadPath;
}
}

















댓글 ( 5)
댓글 남기기