지난번 포스팅에서 구현한 파일업로드의 문제점은, 새로운 파일을 업로드할때
업로드된 파일명과 중복되면 그대로 덮어 쓰게 된다는점이다.
만약 사용자가 파일명만 같고 내용이 다른파일을 업로드 하게된다면 이전의 파일은날라갈것이다.
그렇다면 중복되지 않게 하는 저장 방법은 2가지가 있다.
1. 저장 디렉토리에 중복되는 파일이 존재하면 파일명에 뒤에 숫자를 붙이는 방법이 있고,
파일명에 업로드시간 즉 timestamp 를 붙여주는 방법이 있다
2. 두번쨰 방법은 랜덤한 문자열을 생성해 파일명에 붙여주는 방법도 있다.
이 방법은 UUID를 생성해서 파일명을 랜덤하게 생성시켜주는 방법
이번 예제는 UUID로 처리해볼것이다
1) 파일명이 중복되지 않게 파일 업로드 구현 (UUID)
기존의코드
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
|
@Controller
@Log4j
public class UploadController {
//bean 의 id가 uploadPath인 태그 참조 (xml에 설정된 리소스참조)
@Resource(name="uploadPath")
String uploadPath;
@GetMapping(value = "/upload/uploadForm")
public void uploadForm() {
//upload/uploadForm.jsp로 포워딩
}
//업로드 흐름: 업로드 버튼 클릭 -> 임시디렉토리 업로드 -> 지정된 디렉토리 저장 ->파일정보가 file에 저장
@PostMapping(value ="/upload/uploadForm")
public ModelAndView uploadFomr(MultipartFile file, ModelAndView mav) throws Exception{
log.info("파일이름" + file.getOriginalFilename());
log.info("파일크기" + file.getSize());
log.info("컨텐트타입" + file.getContentType());
//파일 이름을 savedName 변수에 저장
String savedName = file.getOriginalFilename();
//uploadPath경로의 savedName 파일에 대한 file 객체 생성
File target = new File(uploadPath, savedName);
//file의 내용을 target에 복사함
FileCopyUtils.copy(file.getBytes(), target);
//모델앤뷰의 뷰 경로지정
mav.setViewName("upload/uploadResult");
//속성추가
mav.addObject("savedName", savedName);
return mav;
}
}
|
cs |
변경된 코드 - 랜덤으로 생성된 문자열과 원본명을 합치는 메서드를 작성
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
|
@Controller
@Log4j
public class UploadController {
//bean 의 id가 uploadPath인 태그 참조 (xml에 설정된 리소스참조)
@Resource(name="uploadPath")
String uploadPath;
@GetMapping(value = "/upload/uploadForm")
public void uploadForm() {
//upload/uploadForm.jsp로 포워딩
}
//업로드 흐름: 업로드 버튼 클릭 -> 임시디렉토리 업로드 -> 지정된 디렉토리 저장 ->파일정보가 file에 저장
@PostMapping(value ="/upload/uploadForm")
public ModelAndView uploadFomr(MultipartFile file, ModelAndView mav) throws Exception{
//파일 원본 이름 저장
String savedName = file.getOriginalFilename();
log.info("파일이름" + file.getOriginalFilename());
log.info("파일크기" + file.getSize());
log.info("컨텐트타입" + file.getContentType());
//uploadFile 메서드를 사용해 랜덤의 uuid를 생성해 파일이름에 주입 savedName = uploadFile(savedName, file.getBytes());
//모델앤뷰의 뷰 경로지정
mav.setViewName("upload/uploadResult");
//속성추가
mav.addObject("savedName", savedName);
return mav;
}
//파일명 랜덤 생성 메서드
private String uploadFile(String originalName, byte[] fileData) throws Exception{
// uuid 생성
UUID uuid = UUID.randomUUID();
//savedName 변수에 uuid + 원래 이름 추가
String savedName = uuid.toString()+"_"+originalName;
//uploadPath경로의 savedName 파일에 대한 file 객체 생성
File target = new File(uploadPath, savedName);
//fileData의 내용을 target에 복사함
FileCopyUtils.copy(fileData, target);
return savedName;
}
}
|
cs |
구현을 확인해보면 아래와 같은 파일 이름이더라도 덮어 씌워지지않고, 두개의파일로 저장이 되었다
1. 타임스탬프(timestamp)는 특정한 시각을 나타내는 문자열이다.
2. 범용고유식별자(UUID)는 소프트웨어 구축에 쓰이는 식별자 표준