IT/development

[spring] springBoot ajax json과 file 전송

알 수 없는 사용자 2023. 6. 3. 10:21
반응형

controller

/**
 * 게시글 등록 처리(비동기)
 * @param boardVo
 * @param files
 * @return
 */
@PostMapping(value = "/regAjax")
@ResponseBody
public Integer regAjax(@RequestPart(value = "boardVo") BoardVo boardVo,
                       @RequestPart(value = "files", required = false) List<MultipartFile> files,
                       HttpSession session) throws IOException, Exception {
	//테스트니까 try catch로 예외처리 하지 않고 그냥 throws로 던졌다.
    UserVo userInfo = getUserSessionInfo(session);
    boardVo.setUserId(userInfo.getUserId());
	
    //사실 컨트롤러에서는 서비스 하나만 호출하고 그 서비스에서 게시글 등록, 파일 저장까지 처리하는게 좋다.
    boardService.regBoard(boardVo);
    fileService.saveFile(files, boardVo.getBoardNo());

    return boardVo.getBoardNo();
}

 

service

/**
 * 첨부파일 저장
 * @param files
 * @param boardNo
 */
@Transactional
public void saveFile(List<MultipartFile> files, Integer boardNo) throws IOException, Exception {

    if (!files.isEmpty()) {
        FileVo fileVo;

        for (MultipartFile file : files) {
            //원본파일명
            String fileOrgName = file.getOriginalFilename();
            //파일 UUID
            String fileUUid = UUID.randomUUID().toString();
            //파일 확장자
            String extension = fileOrgName.substring(fileOrgName.lastIndexOf("."));
            //서버에 저장될 파일명(UUID+확장자)
            String saveFileName = fileUUid + extension;
            //파일 저장 경로
            String filePath = this.filePath + saveFileName;

            //파일 서버 저장
            file.transferTo(new File(filePath));
            //파일정보 DB 저장
            fileVo = new FileVo();
            fileVo.setBoardNo(boardNo);
            fileVo.setFileOrgName(fileOrgName);
            fileVo.setFilePath(filePath);
            fileVo.setFileSize((int) file.getSize());
            fileMapper.insertFile(fileVo);
            }
        }
}

javascript

//게시글 작성(ajax)
$("#regAjax").on("click", function () {
    if (!confirm("게시글 등록 할거야(ajax)?")) {
        return;

    } else {
        //form 객체 가져와서 새로 생성(기존에 enctype="multipart/form-data"로 되어 있는 form 객체를 가져옴)
        const frm = $("#regFrm")[0];
        const formData = new FormData(frm);
		//multipartFile 가져옴(<input type="file" class="files" name="files" id="files" multiple="multiple"> multiple 옵션을 줘서 여러개 전송 가능)
        let inputFile = $("#files");
		//vo에 바인딩 시킬 데이터
        const params = {
            title: $("#title").val(),
            content : $("#content").val()
        };

        //파일
        formData.append("files", inputFile);
        //vo
        formData.append("boardVo", new Blob([JSON.stringify(params)], {type: "application/json"}));
		
/*========================================================================================*/        
/*        완전 새롭게 formdata 객체를 생성하는 방법은 아래처럼  
/*========================================================================================*/                
	//formdata 새로운 객체 생성
	const formData = new FormData();        
    const params = {
            title: $("#title").val(),
            content : $("#content").val()
        };
        
	//첨부파일
    let fileInput = $(".files");
        for (var i = 0; i < fileInput.length; i++) {
            if (fileInput[i].files.length > 0) {
                for (var j = 0; j < fileInput[i].files.length; j++) {
                    formData.append('files', $('.files')[i].files[j]);
                }
            }
        }        
	//vo
    formData.append("boardVo", new Blob([JSON.stringify(params)], {type: "application/json"}));        
        
/*========================================================================================*/        
/* ajax 전송 부분
/*========================================================================================*/                
        $.ajax({
            url : '/regAjax',
            type : 'post',
            processData: false,
            contentType: false,
            enctype: "multipart/form-data",
            data: formData,
            success: function (result) {
                alert(result + "번 게시글이 등록되었단다.");
                location.href = "/";
            },
            error: function (request, status, error) {
                alert("게시글 등록에 실패했다.");
                location.href = "/";
                console.log(error);
            }
            });
        }
});

개인적으로 비동기로 json과 multipart 전송 때문에 삽질을 꽤나 많이 해서 기록해 둔다.

테스트 결과 여러개 파일 업로드도 가능하다.

반응형