티스토리 뷰
728x90
반응형
SMALL
파일 업로드
1.<form>
태그 이용
- 브라우저의 제한이 없어야하는 경우에 사용.
- 일반적으로 페이지 이동과 동시에 첨부파일을 업로드하는 방식
<iframe>
을 이용해서 화면의 이동 없이 첨부파일을 처리
2.Ajax
를 이용
- 첨부파일을 별도로 처리
<input type='file'>
을 이용하고 Ajax로 처리- HTML5의 Drag and Drop기능이나 jQuery라이브러리를 이용해서 처리하는 방식
파일업로드시 고려할 점
1.동일한 이름으로 업로드되었을 때 기존파일이 사라지는문제.
2.이미지파일의경우, 원본파일의 용량이 큰 경우 섬네일이미지를 생성해야 하는 문제
3.이미지파일과 일반파일을 구분해서 다운로드, 혹은 페이지에서 조회하도록 처리해야하는 문제
4.첨부파일공격에 대비하기위한 업로드파일의 확장자 제한
파일 확장자, 크기 사전 처리
var regex = new RegExp("(.*?\.(exe|sh|zip|alz)$)");
var maxSize = 5242880;
function checkExtension(fileName, fileSize) {
if (fileSize >= maxSize) {
alert("파일 사이즈 초과");
return false;
}
if (regex.test(fileName)) {
alert("해당 종류 파일은 업로드 안됨");
return false;
}
}
중복된 이름 첨부파일 처리
년/월/일 폴더 생성
private String getFolder() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String str = sdf.format(date);
return str.replace("_", File.separator);
}
@PostMapping("/uploadFormAction")
public void uploadFormPost(MultipartFile[] uploadFile, Model model) {
String uploadFolder = "C:\\upload";
// make folder
File uploadPath = new File(uploadFolder, getFolder());
log.info("upload path");
if (uploadPath.exists() == false) {
uploadPath.mkdir();
}
for (MultipartFile multipartFile : uploadFile) {
log.info("=====================================");
log.info("Upload File Name : " + multipartFile.getOriginalFilename());
log.info("Upload File Size : " + multipartFile.getSize());
String uploadFileName = multipartFile.getOriginalFilename();
uploadFileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1);
log.info("only file name : " + uploadFileName);
File saveFile = new File(uploadPath, uploadFileName);
try {
multipartFile.transferTo(saveFile);
} catch (Exception e) {
// TODO: handle exception
log.error(e.getMessage());
}
}
}
중복방지를 위한 UUID 적용
UUID uuid = UUID.randomUUID();
uploadFileName = uuid.toString() + "_" + uploadFileName;
섬네일 이미지 생성
1.pom.xml 추가
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
2.UploadController에 단계별 추가
- 업로드된 파일이 이미지 종류의 파일인지 확인
- 이미지파일의 경우에는 섬네일이미지 생성 및 저장
// 이미지타입인지 검사하는 checkImageType메서드 생성
private boolean checkImageType(File file) {
try {
String contentType = Files.probeContentType(file.toPath());
return contentType.startsWith("image");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return false;
}
3.UploadController에 해당 내용 추가
try {
File saveFile = new File(uploadPath, uploadFileName);
multipartFile.transferTo(saveFile);
if (checkImageType(saveFile)) {
FileOutputStream thumnail = new FileOutputStream(new File(uploadPath, "s_" + uploadFileName));
Thumbnailator.createThumbnail(multipartFile.getInputStream(), thumnail, 100, 100);
thumnail.close();
}
} catch (Exception e) {
// TODO: handle exception
log.error(e.getMessage());
}
브라우저에 별도의 객체를 생성해서 처리하기 위해 jackson-databind 관련 라이브러리 추가
1.pom.xml에 관련 라이브러리 추가
<!-- jackson-databind -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.5</version>
</dependency>
2.AttachfileDTO 클래스 생성
- AttachfileDTO 클래스의 내용
import lombok.Data;
@Data
public class AttachFileDTO {
private String fileName;
private String uploadPath;
private String uuid;
private boolean image;
}
- UploadController에서 AttachFileDTO의 리스트를 반환하는 구조로 변경
@PostMapping(value = "/uploadAjaxAction", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public ResponseEntity<List<AttachFileDTO>> uploadAjaxPost(MultipartFile[] uploadFile) {
List<AttachFileDTO> list = new ArrayList<AttachFileDTO>();
String uploadFolder = "c:\\upload";
String uploadFolderPath = getFolder();
// make folder
File uploadPath = new File(uploadFolder,uploadFolderPath);
if (uploadPath.exists() == false) {
uploadPath.mkdir();
}
// make yyyy/mm/dd folder
for (MultipartFile multipartFile : uploadFile) {
AttachFileDTO attachDTO = new AttachFileDTO();
String uploadFileName = multipartFile.getOriginalFilename();
uploadFileName = uploadFileName.substring(uploadFileName.lastIndexOf("\\") + 1);
log.info("only file name : " + uploadFileName);
attachDTO.setFileName(uploadFileName);
UUID uuid = UUID.randomUUID();
uploadFileName = uuid.toString() + "_" + uploadFileName;
try {
File saveFile = new File(uploadPath, uploadFileName);
multipartFile.transferTo(saveFile);
attachDTO.setUuid(uuid.toString());
attachDTO.setUploadPath(uploadFolderPath);
if (checkImageType(saveFile)) {
attachDTO.setImage(true);
FileOutputStream thumnail = new FileOutputStream(new File(uploadPath, "s_" + uploadFileName));
Thumbnailator.createThumbnail(multipartFile.getInputStream(), thumnail, 100, 100);
thumnail.close();
}
// add list
list.add(attachDTO);
} catch (Exception e) {
// TODO: handle exception
log.error(e.getMessage());
}
}
return new ResponseEntity<List<AttachFileDTO>>(list, HttpStatus.OK);
}
- 해당 jsp파일 수정
$.ajax({
url: '/uploadAjaxAction',
processData: false,
contentType: false,
data: formData,
type: 'POST',
dataType: 'json',
success: function(result) {
console.log(result);
}
});
728x90
반응형
LIST
'Spring boot study > 7. 파일업로드' 카테고리의 다른 글
브라우저에서 섬네일 처리 (0) | 2020.08.14 |
---|
댓글