Part 22. 파일 업로드 상세 처리
22.3 업로드된 파일의 데이터 반환
- 첨부파일 데이터의 업로드가 완료되었지만, 아직도 많은 작업이 남아있다.
- Ajax를 이용해 파일을 업로드했지만, 아직 브라우저 쪽에 아무런 데이터도 전달하지 않았기 때문에 브라우저에서는 어떠한 피드백도 받을 수 없는 상황이다.
- 서버에서 Ajax의 결과로 전달해야 하는 데이터는 업로드된 파일의 경로가 포함된 파일의 이름이다.
- 섬네일의 경우에는 's_'로 시작한다는 규칙만 알고 있으면 필요할 때 사용할 수 있다.
- 브라우저로 전송해야 하는 데이터는 다음과 같은 정보를 포함하도록 설계해야 한다.
- 업로드된 파일의 이름과 원본 파일의 이름
- 파일이 저장된 경로
- 업로드된 파일이 이미지인지 아닌지에 대한 정보
- 이에 대한 모든 정보를 처리하는 방법은 1) 업로드된 경로가 포함된 파일 이름을 반환하는 방식과 2) 별도의 객체를 생성해서 처리하는 방법을 고려할 수 있다.
- 1) 의 경우에는 브라우저 쪽에서 해야 하는 일이 많기 때문에 2)의 방식으로 구성하도록 한다.
- pom.xml에 jackson-databind 관련 라이브러리를 포함한다.
< pom.xml >
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.5</version>
</dependency>
22.3.1 AttachFileDTO 클래스
- org.zerock.domain 패키지에 첨부파일의 정보를 저장하는 AttachFileDTO 클래스를 작성한다.
< AttachFileDTO 클래스 >
package org.zerock.domain;
import lombok.Data;
@Data
public class AttachFileDTO {
private String fileName;
private String uploadPath;
private String uuid;
private boolean image;
}
- AttachFileDTO 클래스에는 원본 파일의 이름(fileName), 업로드 경로(uploadPath), UUID값(uuid), 이미지 여부(image) 정보를 하나로 묶어서 전달하는 용도로 사용한다.
- UploadController는 AttachFileDTO의 리스트를 반환하는 구조로 변경해야 한다.
< UploadController >
@PostMapping(value = "/uploadAjaxAction", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public ResponseEntity<List<AttachFileDTO>>
uploadAjaxPost(MultipartFile[] uploadFile) {
List<AttachFileDTO> list = new ArrayList<>();
// log.info("update ajax post.........");
String uploadFolder = "D:\\upload";
String uploadFolderPath = getFolder();
// make folder -------
File uploadPath = new File(uploadFolder, uploadFolderPath);
log.info("upload path: " + uploadPath);
if(uploadPath.exists() == false) {
uploadPath.mkdirs();
}
// make yyyy/MM/dd folder
for (MultipartFile multipartFile : uploadFile) {
AttachFileDTO attachDTO = new AttachFileDTO();
String uploadFileName = multipartFile.getOriginalFilename();
// IE has file path
uploadFileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1);
log.info("only File name : " + uploadFileName);
attachDTO.setFileName(uploadFileName);
UUID uuid = UUID.randomUUID();
uploadFileName = uuid.toString() + "_" + uploadFileName;
// File saveFile = new File(uploadFolder, uploadFileName);
try {
File saveFile = new File(uploadPath, uploadFileName);
multipartFile.transferTo(saveFile);
attachDTO.setUuid(uuid.toString());
attachDTO.setUploadPath(uploadFolderPath);
// check image type file
if (checkImageType(saveFile)) {
attachDTO.setImage(true);
FileOutputStream thumbnail = new FileOutputStream(new File(uploadPath, "s_" + uploadFileName));
Thumbnailator.createThumbnail(multipartFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
}
// add to List
list.add(attachDTO);
} catch (Exception e) {
// log.error(e.getMessage());
e.printStackTrace();
} //end catch
} //end for
return new ResponseEntity<>(list, HttpStatus.OK);
}
- uploadAjaxPost()는 기존과 달리 ResponseEntity<List< AttachFileDTO>>를 반환하는 형태로 수정하고, JSON 데이터를 반환하도록 변경된다.
- 내부에서는 각 파일에 맞게 AttachFileDTO를 생성해 전달하는 구조로 변경된다.
22.3.2 브라우저에서 Ajax 처리
- /uploadAjax에서는 결과 데이터를 JavaScript를 이용해 반환된 정보를 처리하도록 수정한다.
< uploadAjax.jsp >
$.ajax({
url: '/uploadAjaxAction',
processData: false,
contentType: false,
data: formData,
type: 'POST',
dataType:'json',
success: function(result){
console.log(result);
}
}); //$.ajax
- Ajax를 호출했을 때의 결과 타입(dataType)은 'json'으로 변경하고, 결과를 console.log()로 찍도록 변경한다.
- 첨부파일을 업로드한 후에는 브라우저에서 결과를 아래와 같이 확인할 수 있다.