내가 보려고 정리하는 블로그
첨부파일에 관한 기능 (멀티파일 업로드) 본문
기존의 multipart를 이용하여 파일 목록에 원하는 파일을 2개 이상 한 번에 지정할 수 있으며
원하지 않는 파일을 삭제 후 업로드하는 기본적인 기능이지만 어려웠던 파일업로드 소스이다.
우선 이 기능의 주요점은 업로드할 파일을 선택할때 멀티로 파일을 선택할 수 있어야 하고 선택 후 다시 선택한 다름 파일 역시 한 번에 업로드가 가능해야 하고 선택 후 리스트에 담겨있는 파일을 하나씩 삭제하여 업로드할 수 있어야 한다.
예를 들어 1번 2번파일을 먼저 선택하면 화면에 1번과 2번의 파일을 보여주고 추가로 3번과 4번 파일을 선택하면 1,2,3,4번의 파일이 화면에 보여야 하며 화면에 등록된 파일 중 1번 파일을 삭제하면 2,3,4번의 파일만 보이고 업로드 시 2,3,4번의 파일을 업로드시킨다.
우선 controller
@RequestMapping(value= "fileUpload.do")
public String fileUpload( MultipartHttpServletRequest multiRequest ,HttpServletRequest req,) throws Exception{
List<MultipartFile> fileList = multiRequest.getFiles("uploadFile");
//업로드한 파일이 없으면 실행되지 않음
if(fileList != null){
//파일이 저장될 경로 설정
String path = "C:/File/";
File dir = new File(path);
if(!dir.isDirectory()){
dir.mkdirs();
}
if(!fileList.isEmpty()){
//넘어온 파일을 리스트로 저장
for(int i = 0; i < fileList.size() ; i++){
//파일 중복명 처리
String random = UUID.randomUUID().toString();
//원래 파일명
String originalfilename = fileList.get(i).getOriginalFilename();
//저장되는 파일이름
String saveFileName = random + "_"+ originalfilename;
//저장될 파일 경로
String savePath = path + saveFileName;
//파일사이즈
int fileSize = (int) fileList.get(i).getSize();
//파일 저장
fileList.get(i).transferTo(new File(savePath));
FileFlVO fileFlVO = new FileFlVO(flGrpNo, originalfilename, savePath, fileSize);
}
}
}
return "파일 저장 후 이동할 페이지";
}
파일을 리스트 형태로 받아서 하나씩 저장한다.
파일 저장에 대한 소스는 다른 것을 참고하여도 무방하다.
가장 중요한 건 jsp파일이다.
우선 input 태그를 숨겨 놓고 다른 버튼 클릭 시 숨겨놓은 input 태그가 실행되도록 한다.
<input type="file" id="multi-add" class="btn-add" multiple style="display: none;" name="file" >
<button type="button" class="btn-add" id="file_add">파일추가</button>
$("#file_add").on('click',function(){ $('#multi-add').click(); });
이런 식으로 파일 추가라는 버튼 클릭 시 display : none 설정을 해놓은 input파일을 실행할 수 있도록 한다.
그 이후 script단으로 새로운 arr을 만들어 파일 객체를 배열에 담아 컨트롤한다.
var $fileListArr = new Array();
var $totSize = 0;
var $keyNum = 0;
var $limit = 0;
$("#multi-add").on('change',function(){
var files = $(this)[0].files;
var fileArr = new Array();
fileArr = $fileListArr;
$limit = $totSize;
for(var i = 0 ; i < files.length ; i++){
$limit = $limit + files[i].size;
if($limit > 20000000){
alert("첨부파일 용량은 20MB를 넘길수 없습니다.");
return false;
}
}
for(var i = 0 ; i < files.length ; i++){
$('#file_table').append("<tr id=file"+ $keyNum +"><td class='txt-c'><button type='button' style='color: #A4A4A4; font-size: large;' class='deleteFile' >⊝</button></td>"+
"<td>"+ files[i].name +"</td>"+
"<td id='fileSize "+ $keyNum +"'><p class=file"+ $keyNum +">"+ Math.floor(files[i].size / 1000) +" KB</p></td>"+
"</tr>");
$keyNum++;
fileArr.push(files[i]);
$totSize = $totSize + files[i].size;
}
$fileListArr = new Array();
$fileListArr = fileArr;
$('#totSize').text("");
$('#totSize').text(Math.floor($totSize / 1000000));
});
//파일 delete
$(document).on("click" , '.deleteFile', function(){
//삭제할 파일의 아이디
var DeleteID = $(this).parent().parent().attr('id');
//삭제하려는 파일의 크기값(텍스트)
var DeleteFileSize = $(this).parent().next().next().children('p').text();
//삭제하는 파일의 크기값(바이트)
var fileSizeByteArr = new Array();
fileSizeByteArr = DeleteFileSize.split(' ');
var fileSize = Number(fileSizeByteArr[0]) * 1000;
//배열에서 삭제를 위한 번호
var DeleteArrNum = DeleteID.substring(DeleteID.length , DeleteID.length -1);
var fileArr = $fileListArr;
fileArr.splice(DeleteArrNum , 1);
$keyNum = 0
$fileListArr = new Array();
$('#file_table').children().remove();
$totSize = 0;
for(var i = 0 ; i < fileArr.length ; i++){
$('#file_table').append("<tr id=file"+ $keyNum +"><td class='txt-c'><button type='button' style='color: #A4A4A4; font-size: large;' class='deleteFile' >⊝</button></td>"+
"<td>"+ fileArr[i].name +"</td>"+
"<td id='fileSize "+ $keyNum +"'><p class=file"+ $keyNum +">"+ Math.floor(fileArr[i].size / 1000) +" KB</p></td>"+
"</tr>");
$keyNum++;
$fileListArr.push(fileArr[i]);
$totSize = $totSize + fileArr[i].size;
}
$limit = $totSize;
$('#totSize').text("");
$('#totSize').text(Math.floor($totSize / 1000000));
});
파일의 추가 또는 삭제 시 스크립트단에서 만들어 놓은 배열로 실제 값을 다루며 배열의 파일 객체를
화면에 보여준다.
이후 업로드 시
//저장버튼 클릭시
$('#submit').click(function(){
var formData = new FormData();
for(var i = 0; i < $fileListArr.length ; i++){
formData.append("uploadFile" , $fileListArr[i]);
}
$.ajax({
url:"/file/fileUpload.do",
processData : false,
contentType : false,
data: formData ,
type : 'POST',
success : function(res){
location.href = '/file/List.do';
},
error: function(){
alert('에러');
}
});
}else{
return false;
}
});
위처럼 배열에 담긴 파일 객체를 FormData로 하나씩 담아서 Controller로 전달하면 원하는 데로 파일을 업로드할 수 있다.