Spring

Spring 파일 업로드 심화

테라시아 2024. 12. 31. 06:38

* UUID(Universally Unique ID)
  네트워크 상에서 각각의 개체들을 식별하기 위해서 사용
  중복될 가능성이 없다고 보면 됨

 

☆ Code

 

★ UploadContriller.java

package com.koreait.board.controller;

import java.io.File;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.koreait.board.bean.AttachFileVO;

import lombok.extern.slf4j.Slf4j;

@Controller
@Slf4j
@RequestMapping("/upload/*")
public class UploadController {
	
	@PostMapping(value="uploadAjaxAction", produces=MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public List uploadAjaxPost(MultipartFile[] uploadFile) {
		log.info("[uploadController] uploadAjaxPost() Called OK");
		
		List<AttachFileVO> fileList = new ArrayList();
		
		String uploadFolder = "C:/upload/temp";
		String uploadFolderPath = getFolder();
		// yyyy/mm/dd 경로 생성
		File uploadPath = new File(uploadFolder, uploadFolderPath);
		
		if(uploadPath.exists()) {
			log.info("이미 디렉토리가 존재합니다.");
		}
		else {
			uploadPath.mkdirs();
		}
		
		for(MultipartFile f : uploadFile) {
			log.info("filename : " + f.getOriginalFilename());
			log.info("filesize : " + f.getSize());
			
			String uploadFileName = f.getOriginalFilename();
			UUID uuid = UUID.randomUUID();
			log.info("uuid : " + uuid.toString());
			uploadFileName = uuid.toString() + "_" + uploadFileName;
			
			AttachFileVO attachFileVO = new AttachFileVO();
			attachFileVO.setFileName(uploadFileName);
			attachFileVO.setUuid(uuid.toString());
			attachFileVO.setUploadPath(uploadFolderPath);
			
			
			File saveFile = new File(uploadPath, uploadFileName);
			
			try {
				f.transferTo(saveFile);
				
				if(checkImageType(saveFile)) {
					log.info("Image File");
					attachFileVO.setImage(true);
				}
				else {
					log.info("Not Image File");
				}
			}
			catch(Exception e) {
				e.printStackTrace();
			}
			
			fileList.add(attachFileVO);
		}		
		return fileList;
	}
	
	private boolean checkImageType(File file) {
		try {
			String contentType = Files.probeContentType(file.toPath());
			log.info("ContentType : " + contentType);
			return contentType.startsWith("image");
		}
		catch(Exception e) { e.printStackTrace(); }
		
		return false;
	}
	
	private String getFolder() {
		String str = null;
		
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		str = sdf.format(date);
		
		return str;
	}
}

 

★ register.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write</title>
</head>
<body>
	<h1>마음대로 글을 쓰셔도 될까요?</h1>
	<hr>
	<form action="/board/register" method="post">
		<p>title : <input type="text" name="title"></p>
		<p>content : <br><textarea name="content"></textarea></p>
		<p>writer : <input type="text" name="writer"></p>
		
		<div class="uploadDiv">
			<input type="file" name="uploadFile" multiple style="width: 200px;">
		</div>
		<div class="uploadResult">
			<ul>
			<!-- 
				<li>File1</li>
				<li>File2</li>
			-->
			</ul>
		</div>		
		<input type="submit" value="Register">
	</form>
</body>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<script>
	$("input[type='file']").change(function(e){
		let inputFile = $("input[name='uploadFile']");
		let files = inputFile[0].files;
		console.log(files);
		
		let formData = new FormData();
		
		for(let i=0; i<files.length; i++){
			if(checkFile(files[i].name, files[i].size) == false){
				alert("파일 업로드 실패");
				return;
			}
			
			formData.append("uploadFile", files[i]);
		}
		
		console.log(formData);
		
		$.ajax({
			url: "/upload/uploadAjaxAction",
			processData: false,
			contentType: false,
			data: formData,
			type: "POST",
			success: function(result){
				alert("File Upload Completed");
				console.log(result);
				inputFile.val("");
				showUploadFile(result);
			},
			error: function(error){
				console.log("야 오류났어");
				console.log(error);
			}
		});
		
	});

	function checkFile(fileName, fileSize){
		let MAXSIZE = 5000000;
		
		if(fileSize > MAXSIZE){
			alert("파일 사이즈가 왜 이렇게 큰가요");
			return false;
		}
		
		let RULE = new RegExp("(.*?)\.(exe|sh|zip|alz)$");
		if(RULE.test(fileName)){
			alert("이런 파일 올리시면 혼납니다.")
			return false;
		}
		
		return true;
	}
	
	function showUploadFile(fileArray){
		let uploadResult = $(".uploadResult ul");
		
		let str = "";
		
		$(fileArray).each(function(i, obj){
			str += "<li>";
			if(obj.image) str += "<image src='/img/image.png' width='16px'> ";
			else          str += "<image src='/img/attach.png' width='16px'> ";
			str += obj.fileName.substring(obj.fileName.indexOf("_")+1);
			str += "</li>";
		});
		
		console.log(str);
		uploadResult.append(str);
		
	}
</script>
</html>