파일 업로드 게시판
파일 업로드가 되는 게시판은 대부분의 사이트에 꼭 하나씩 있습니다. 사이트를 구축할 때 기본이 되는 파일 업로드이지만 불편함 없이 다양한 기능이 필요할 때도 있습니다. 어디에서나 쓸 수 있게 모듈화를 해놓았고, 정리를 해놓았으며 해당 내용을 공유하고자 합니다.
앞전에는 커스터마이징에 대한 간단한 방법을 정리를 공유했으며, 이번에는 2번 type="file" multiple="multiple"를 통하여 다중 파일 업로드와, AJAX를 통한 스프링 파일 업로드, 그리고 다중 파일 업로드 진행 시 개별 파일 삭제, 개수 제한까지 구현해보겠습니다.
1. input type="file" UI 스타일변경(커스터마이징) 링크
2.
- 다중 파일업로드(멀티파일 업로드)
- AJAX로 SPRING 파일 업로드
- input file multiple 부분(선택) 삭제 후 업로드 & input file multiple max (개수 제한)
기본 세팅 pom.xml , servlet-context.xml
pom.xml
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<!-- 대용량 파일 처리 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- commons-fileupload -->
<!-- multipart등을 사용할수 있음 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
servlet-context.xml
<!-- 개인적인 위치기 때문에 원하시는 위치를 잡으셔도 됩니다~ -->
<resources mapping="/**" location="/resources/" />
<!-- 스프링에서 기본으로 제공하는 multipartResolver는 CommonsMultipartResolver 이므로, 순수한 multipartResolver를 사용하기 위해 빈 이름으로 "multipartResolver"를 등록해야함 + 프로퍼티를 이용 최대 가능한 업로드 사이즈 지정함 -->
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="10000000"></beans:property>
</beans:bean>
사용자 페이지(VIEW)
HTML & JAVASCRIPT & JQUERY
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html lang="en">
<head>
<title>파일업로드예제</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>파일업로드</h2>
<form name="dataForm" id="dataForm" onsubmit="return registerAction()">
<button id="btn-upload" type="button" style="border: 1px solid #ddd; outline: none;">파일 추가</button>
<input id="input_file" multiple="multiple" type="file" style="display:none;">
<span style="font-size:10px; color: gray;">※첨부파일은 최대 10개까지 등록이 가능합니다.</span>
<div class="data_file_txt" id="data_file_txt" style="margin:40px;">
<span>첨부 파일</span>
<br />
<div id="articlefileChange">
</div>
</div>
<button type="submit" style="border: 1px solid #ddd; outline: none;">전송</button>
</form>
</div>
<!-- 파일 업로드 스크립트 -->
<script>
$(document).ready(function()
// input file 파일 첨부시 fileCheck 함수 실행
{
$("#input_file").on("change", fileCheck);
});
/**
* 첨부파일로직
*/
$(function () {
$('#btn-upload').click(function (e) {
e.preventDefault();
$('#input_file').click();
});
});
// 파일 현재 필드 숫자 totalCount랑 비교값
var fileCount = 0;
// 해당 숫자를 수정하여 전체 업로드 갯수를 정한다.
var totalCount = 10;
// 파일 고유넘버
var fileNum = 0;
// 첨부파일 배열
var content_files = new Array();
function fileCheck(e) {
var files = e.target.files;
// 파일 배열 담기
var filesArr = Array.prototype.slice.call(files);
// 파일 개수 확인 및 제한
if (fileCount + filesArr.length > totalCount) {
$.alert('파일은 최대 '+totalCount+'개까지 업로드 할 수 있습니다.');
return;
} else {
fileCount = fileCount + filesArr.length;
}
// 각각의 파일 배열담기 및 기타
filesArr.forEach(function (f) {
var reader = new FileReader();
reader.onload = function (e) {
content_files.push(f);
$('#articlefileChange').append(
'<div id="file' + fileNum + '" onclick="fileDelete(\'file' + fileNum + '\')">'
+ '<font style="font-size:12px">' + f.name + '</font>'
+ '<img src="/img/icon_minus.png" style="width:20px; height:auto; vertical-align: middle; cursor: pointer;"/>'
+ '<div/>'
);
fileNum ++;
};
reader.readAsDataURL(f);
});
console.log(content_files);
//초기화 한다.
$("#input_file").val("");
}
// 파일 부분 삭제 함수
function fileDelete(fileNum){
var no = fileNum.replace(/[^0-9]/g, "");
content_files[no].is_delete = true;
$('#' + fileNum).remove();
fileCount --;
console.log(content_files);
}
/*
* 폼 submit 로직
*/
function registerAction(){
var form = $("form")[0];
var formData = new FormData(form);
for (var x = 0; x < content_files.length; x++) {
// 삭제 안한것만 담아 준다.
if(!content_files[x].is_delete){
formData.append("article_file", content_files[x]);
}
}
/*
* 파일업로드 multiple ajax처리
*/
$.ajax({
type: "POST",
enctype: "multipart/form-data",
url: "/file-upload",
data : formData,
processData: false,
contentType: false,
success: function (data) {
if(JSON.parse(data)['result'] == "OK"){
alert("파일업로드 성공");
} else
alert("서버내 오류로 처리가 지연되고있습니다. 잠시 후 다시 시도해주세요");
},
error: function (xhr, status, error) {
alert("서버오류로 지연되고있습니다. 잠시 후 다시 시도해주시기 바랍니다.");
return false;
}
});
return false;
}
</script>
</body>
</html>
전체적인 원리는 다음과 같습니다.
1. input type="file" multiple="multiple"이 동작할때(document ready에서 실행), 해당 파일을 가져와서 배열에 담아주고 input file은 초기화 해줍니다.
*input file multiple 특성상 중복파일은 업로드가 되지 않습니다. 초기화를 해야 중복파일도 업데이트가 가능해집니다.
2. 파일을 담고 -이미지를 클릭했을때 delete 되었다고 변경합니다.
3. ajax로 보낼때 delete된것을 제외하고 보냅니다.
JAVA
SPRING
@ResponseBody
@RequestMapping(value = "/file-upload", method = RequestMethod.POST)
public String fileUpload(
@RequestParam("article_file") List<MultipartFile> multipartFile
, HttpServletRequest request) {
String strResult = "{ \"result\":\"FAIL\" }";
String contextRoot = new HttpServletRequestWrapper(request).getRealPath("/");
String fileRoot;
try {
// 파일이 있을때 탄다.
if(multipartFile.size() > 0 && !multipartFile.get(0).getOriginalFilename().equals("")) {
for(MultipartFile file:multipartFile) {
fileRoot = contextRoot + "resources/upload/";
System.out.println(fileRoot);
String originalFileName = file.getOriginalFilename(); //오리지날 파일명
String extension = originalFileName.substring(originalFileName.lastIndexOf(".")); //파일 확장자
String savedFileName = UUID.randomUUID() + extension; //저장될 파일 명
File targetFile = new File(fileRoot + savedFileName);
try {
InputStream fileStream = file.getInputStream();
FileUtils.copyInputStreamToFile(fileStream, targetFile); //파일 저장
} catch (Exception e) {
//파일삭제
FileUtils.deleteQuietly(targetFile); //저장된 현재 파일 삭제
e.printStackTrace();
break;
}
}
strResult = "{ \"result\":\"OK\" }";
}
// 파일 아무것도 첨부 안했을때 탄다.(게시판일때, 업로드 없이 글을 등록하는경우)
else
strResult = "{ \"result\":\"OK\" }";
}catch(Exception e){
e.printStackTrace();
}
return strResult;
}
완성본
정리
SPRING에서 input file multiple과 AJAX multipart/form-data처리 파일 선택 업로드, 파일 선택 삭제, 다중 파일 업로드 개수 제한까지 다 가능한 소스입니다.
이 정도 예제를 잘 가공해서 사용하면 충분히 어떤 게시판에서든 활용이 가능할 겁니다.
혹시라도 구현 진행 중에 안 되는 부분 있으시면 댓글 남겨주시면 소스 보내드릴게요~
또한 내용상 오류가 있거나 잘못된 점이 있으면 댓글 남겨주시면 진심으로 감사하겠습니다!
'Language > Spring' 카테고리의 다른 글
[SPRING] 애플 로그인 API 쉽게 구현 방법 및 예제 - OAuth 2.0, Javascript, Jsp (2861) | 2021.08.20 |
---|---|
[SPRING] 카카오 로그인 스프링 Rest API 예제 및 쉬운 구현 방법 - OAuth 2.0, Javascript, Jsp (378) | 2021.07.15 |
파일 업로드 쉽게 구현하기 커스터마이징하기(css변경,스타일변경,디자인) ① (248) | 2021.05.28 |
[JAVA, SPRING, Iamport] 아임포트 페이팔 연동(WEB,APP) (395) | 2021.03.18 |
[JAVA, SPRING, Iamport] 아임포트 모바일 웹뷰 콜백함수 해결책 및 자바 예제(WEB,APP) (254) | 2021.03.17 |
댓글