Backend/SpringBoot

Java / SpringBoot AJax를 통한 비동기 파일 업로드(File Upload)

LookAtMe 2024. 6. 7. 11:50

Java Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
 
@RestController
@RequestMapping("/controller")
public class Controller
{
    private final String UPLOADPATH = InitializeProperties.getProperty("file.root.path"+ "/"; // application.properties에서 읽어옴
 
    private final LocalDateTime localDateTime = LocalDateTime.now();
 
    /* 파일업로드 */
    @PostMapping(value = "/ajax/fileUpload.do")
    public ResponseEntity<Object> fileName(
            @RequestParam(value = "deletePath", required = false) List<String> deletePathList,
            @RequestParam(value = "deleteFileName", required = false) List<String> deleteFileNameList,
            @RequestParam(value = "servicePath", required = falseString servicePath,
            @RequestParam(value = "uploadFile", required = true) List<MultipartFile> files,
            MultipartHttpServletRequest request)
    {
        System.out.println("deletePath : " + deletePathList);
        System.out.println("deleteFileName : " + deleteFileNameList);
        System.out.println("servicePath : " + servicePath);
        System.out.println("uploadFile : " + files.size());
 
        List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> hashMap = null;
        String name = "", fileName= "", pakageName = "", uploadedFileName = "", uploadPath = "";
        int fileSize = 0;
 
        if(deletePathList != null && deletePathList.size() > 0 && deleteFileNameList != null && deleteFileNameList.size() > 0// 삭제할 파일 경로랑 파일이름이 들어온 경우 파일 삭제
        {
            for(int i = 0; i < deleteFileNameList.size(); i++)
            {
                deleteFile(deletePathList.get(i) + deleteFileNameList.get(i));
            }
        }
 
        for(MultipartFile file: files)
        {
            try
            {
                hashMap = new HashMap<String, Object>();
                name = file.getName();                 //필드 이름 얻기
                fileName = file.getOriginalFilename(); //파일명 얻기
                fileSize = file.getBytes().length;        //파일 사이즈
                pakageName = fileName.substring(fileName.lastIndexOf(".")); // 파일 확장자
 
                uploadedFileName = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "_" + UUID.randomUUID().toString().replaceAll("-"""+ pakageName; //업로드 파일명
 
                uploadPath = (servicePath != null && servicePath.length() > 0) ? UPLOADPATH + servicePath : UPLOADPATH;
 
                mkdir(uploadPath);
 
                if(file.getSize() > 0// 파일 크기가 0이면 저장안함
                    file.transferTo(new File(uploadPath + uploadedFileName)); // 서버에 파일 저장
 
                System.out.println("uploadFilePath : " + uploadPath + uploadedFileName);
 
                hashMap.put("success""Y"); // 성공여부
                hashMap.put("name", name); // html 필드명
                hashMap.put("fileName", uploadedFileName); // 업로드 파일명 오늘날짜_UUID.확장자
                hashMap.put("filePath", uploadPath); // 파일경로
                hashMap.put("originName", fileName); // 원본 파일명
                hashMap.put("fileSize", fileSize); // 파일 사이즈
                hashMap.put("fileExt", pakageName); // 파일 확장자
                list.add(hashMap);
            }
            catch (Exception e)
            {
                e.printStackTrace();
                return new ResponseEntity<Object>("file error", HttpStatus.BAD_REQUEST);
            }
        }
        if(list.size() == 1)
            return new ResponseEntity<Object>(hashMap, HttpStatus.OK);
        else
            return new ResponseEntity<Object>(list, HttpStatus.OK);
    }
 
    private void mkdir(String filePath) throws Exception
    {
        if(!Files.exists(Paths.get(filePath)))
        {
            Files.createDirectories(Paths.get(filePath));
            System.out.println("mkdir : " + filePath);
        }
    }
 
    private void deleteFile(String deleteFile)
    {
        if(new File(deleteFile).delete())
        {
            System.out.println("deleteFile : " + deleteFile);
        }
    }
}
cs

 

Javascript Code + JQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
 * 파일 확장자 체크 
 * @param {"this"} fileObj 
 * @param {"fileExt"} fileExt 
 * @param {"servicePath"} servicePath 
 * @return void
*/
function fn_uploadFileCheck(fileObj, fileExt, servicePath)
{
    const allowedExt = fileExt ? new RegExp('\\.' + fileExt + '$''i') : /.*/;
    let fileDate;
    let formData = new FormData();
    
    for (let i = 0; i < fileObj.files.length; i++
    {
        fileDate = fileObj.files[i].name;
        if(!allowedExt.exec(fileDate)) 
        {
             alert("Only " + fileExt + " files can be registered.");
             fileObj.value = "";
             return;
        } 
        formData.append("uploadFile", fileObj.files[i]);
    }
 
    if(fileDataList != null)
    {
        if(fileDataList.length)
        {
            for(let i = 0; i < fileDataList.length; i++)
            {
                formData.append("deleteFileName", fileDataList[i].fileName);
                formData.append("deletePath", fileDataList[i].filePath);
            }
        }
        else
        {
            formData.append("deleteFileName", fileDataList.fileName);
            formData.append("deletePath", fileDataList.filePath);
        }
    }
    if(servicePath) formData.append("servicePath", servicePath);
       return fn_uploadFile(formData, servicePath).then(function(response) 
       {
        return response;
    }).catch(function(error) 
    {
        console.error(error);
    }); // ajax 파일 업로드
}
 
let fileDataList = null;
 
/**
 * 파일 업로드 후 파일 데이터 fileDataList 넣어줌
 * @param {"formData"} formData 
 * @return void
*/
function fn_uploadFile(formData)
{
    return new Promise(function(resolve, reject) 
    {
        $.ajax({
            type: "POST",
            url: "/mte/common/ajax/fileUpload.do",
            data: formData,
            processData: false,
            contentType: false,
            cache: false,
            success: function(res) 
            {
                if (res != "file error"
                {
                    fileDataList = res;
                    resolve(res);
                } 
                else 
                {
                    alert(res);
                    reject("파일 업로드 실패: " + res);
                }
            },
            error: function(xhr, error, msg) 
            {
                console.log(error);
            },
        });
    });
}
cs

 

HTML 

1
<input type="file" accept=".pdf" onchange="fn_uploadFileCheck(this, 'pdf', '추가경로/')"/>
cs