본문 바로가기

programming/웹프로그래밍

[spring] 로컬 파일에 이미지 저장과 예외처리 - (SimpleDateFormat), Clone Coding

반응형

1. 개요

 

 바로 직전 포스팅이 바로 Spring에서 이미지를 저장하는 방법이다. 이 방법에서 심각한 문제를 발견하였다. 우리가 웹 사이트를 만들면 다양한 사람이 사이트를 사용한다. 이런 경우를 생각해서 예외처리에 철저해야 한다는 것일 이번에 깨닫게 되었다. 이 포스팅은 내가 전에 올린 포스팅과 이어지는 내용이기에 꼭 전 포스팅을 보고왔으면 좋겠다.


이전 포스팅: apape1225.tistory.com/66

 

[spring] 로컬 파일에 Img 저장하기! - (ServletContext)

1. 개요  Django를 공부하다가 동기에게 실속있게 도움되는 프로젝트를 해보자는 제안이 왔다. 프로젝트에 목말라있던 나에게는 아주 좋은 기회였다. 바로 승낙했지만 정말 충격이었다...... Clone

apape1225.tistory.com


 위의 포스팅을 봤으면 다음 상황을 보도록 하자.

 

 사용자 A와 B 둘다 img1.jpg라는 파일을 가지도 있다고 생각해보자. 다음과 같은 상황이 될 것이다.



 사용자 A가 img1.jpg 라는 이름이 이미지 파일을 내 웹 사이트에 저장한다고 생각해보자. 그럼 나의 out폴더 하위에 resource파일 밑에 img 파일에는 img1.jpg라는 이름의 파일이 저장 될 것이다. 다음과 같은 상황이다.



 그 후 다른 사용자 B가 img1.jpg라는 이름의 파일을 다시 저장한다면 로컬 파일인 img파일은 img1.jpg라는 파일이 두개나 존재하게 되고 이는 큰 에러이다. (윈도우 같은 경우 후에 들어온 img1.jpg의 파일이 img1(1).jpg라는 이름의 파일로 바뀌겠지만 파일의 이름이 바뀌었으니 이런 상황도 심각한 오류이다.) 그림으로 표현하면 다음과 같을 것이다.



 이번 포스팅에서는 위의 상황에 대체하는 방법을 알아보자.

 

2. 해결방법

 

 이 문제를 해결하려면 이미지 각각의 고유의 번호를 매기는 것이 하나의 방법이라고 생각되었다. 그렇다면 전역변수 하나를 선언해서 이미지 파일 앞에 붙여주면 될까? 이것도 방법이겠지만 내가 찾아본 방법은 날짜를 이용하는 것이다. 알고리즘은 다음과 같다.


  1. 파일이 입력되는 순간의 날짜와 시간을 저장한다. (SimpleDateFormat 사용)
  2. 저장된 날짜와 시간을 이미지 파일 이름 앞에 저장한다.
  3. 새로운 이름으로 파일을 서버에 저장해준다.

 이렇게 되면 같은 날 같은 시간의 같은 초에 같은 미리 초 까지 똑같이 파일을 저장해주지 않는 이상 파일의 이름이 겹칠 일이 없다. 다음은 소스코드이다.

 

- 소스코드

 

//SimpleDateFormat을 이용해 날짜를 입력받는다.
private final SimpleDateFormat dateForServer = new SimpleDateFormat("yyyyMMddHHmmss_");

@PostMapping("/admin/addLecture")
    public String insert(LectureDto lectureDto, MultipartFile lecImage) throws IOException {

        Date currentTime = new Date();
        String regDateForServer = dateForServer.format(currentTime);
        
        //이미지 앞에 포멧한 데이터를 저장
        String fullName = relativePath + regDateForServer + lecImage.getOriginalFilename();

		//이 부분은 포스팅과는 상관 없는 부분이니 무시해도 좋다.
        lectureDto.setLecRegDate(regDateForDB); // 현재시간 저장
        lectureDto.setLecImg(fullName); // 이미지이름 저장
        lectureDto.setLecLike("0");
        
        //root_path를 입력받고 filename_server에 최종적으로 저장될 파일경로와 파일의 이름을 저장한다.
        String root_path = servletContext.getRealPath("/");
        String filename_server = root_path + fullName;

        FileCopyUtils.copy(lecImage.getBytes(), new File(filename_server)); // 서버에 저장
        lectureService.insertLecture(lectureDto); // DB에 저장

        return "redirect:/admin/lecture/data-table";
    }

 

 사실 이것 말고도 많은 부분을 담당했지만 포스팅을 못하고 있다. 꼭 많은 글들을 올렸으면 좋겠다.

반응형