파일을 업로드 하고 다운로드 받는 과정에서 저장소에 동일한 파일이름을 가진 파일을 업데이트 하게 되면 저장되는 파일의

이름을 바꾸어 주어야 한다.


동일한 이름이 있을때마다 파일명 뒤에 카운트숫자를 달아 주는 방법을 사용한다거나 

UUID 같은 것을 파일명으로 바꾸고 저장한다거나 날짜순으로 저장하는등의 여러가지 방법들이 있다.


그렇다면 다운 받을때는 파일명이 uuid나 일반 사용자가 알아보기 힘든 파일명을 사용하면 안되기 때문에


다운로드 받을때는 다시 원래 파일명으로 다운 받도록 해주어야 한다.


그렇기 위해서는 파일업로드와 함께 DB에 해당 파일의 이름이나 이름이 포함된 경로를 넣으며 실제저장되는 변경된 파일이름과 원본파일의 이름 두가지를 넣어 주어야 한다.


문제는 여기서 발생한다. 흔히 나와있는 파일 업/다운로드 로직이나 전자정부 프레임워크를 사용하다보면 파일을 다운받을때 실제 저장된 파일이름만 가져와서 다운로드 받는 로직으로 짜여져 있고 단순히 복사해서 붙여넣기를 하는 방법으로 사용하니 다운받을때 디비에서 이름두가지를 가지고 오고 나서 이후에 어떻게 해야 할지 모르는 경우가 생긴다.


대표적으로 컨트롤러에서 


 return new ModelAndView("download", "downloadFile", file); 


이렇게 리턴값을 modelAndView로 사용하는 방법에서 실제저장된 파일명을 바꿔서 사용하는 방법을 알아보자.




일단 리턴되는  ModelAndView("download", "downloadFile", file) 여기서 


'download'는 dispatcher-servlet.xml 에서 지정되는 값으로. 디스패쳐 파일을 열고나서 download을 검색해 보면



<bean id="download" class="egovframework.XXXXXXXX.XXXXXXX.XXXXXXXX.DownloadView" />


와 같은 형식으로 쓰여 있을 것이다. 'download'라는 요청을 받으면 해당 클래스를 실행하겠다는 중간의 XXX표는 패키지 경로이다.


DownloadView 클래스를 열어 보면 



File file = (File) model.get("downloadFile"); <- 이런식으로 modelAndView의 두번째 인자를 불러오며 결과는 downloadFile뒤에 쓰여진 file이 된다.



아래로 좀 내려보면 


fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");


이런식으로 해당 파일의 이름을 꺼내서 


 response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");


이렇게 파일이름을 셋팅을 하는데


여기서 셋팅되는 fileName만 원래 파일이름으로 바꿔주면 되는 것이다.




이제부터 어떻게 해야 하는지 방법을 알아보자



우선 다운로드 URL이 어노테이션 되어 있는 컨트롤러에서 


리턴되는 값을 return new ModelAndView("download", "downloadFile", file); 가 있는 컨트롤러를




fileName = new String(fileName.getBytes("iso-8859-1"), "UTF-8"); // 파일이름 깨지니까 인코딩

    realName = new String(realName.getBytes("iso-8859-1"), "UTF-8");

//propertiesService.getString("Globals.FmsFilePath")는 미리 지정해놓은 경로니까 그냥 파일경로라고 생각하면 됨

    String fullPath = propertiesService.getString("Globals.FmsFilePath") + "\\경로\\" + fileName;

    

   File file = new File(fullPath); // 실제 파일 경로를 지정해 생성한 파일

   File file2 = new File(realName); // 바꿀 파일이름만 넣어놓은 파일  realName은 String값이다.


   ModelAndView mav = new ModelAndView();

   mav.setViewName("download");

   mav.addObject("downloadFile", file); // 실제 저장된 파일

   mav.addObject("realFileName", file2); //db에 저장해 놓은 원래 파일이름

   

   if(!file.exists()){

    return null;

   }

    //    return new ModelAndView("download", "downloadFile", file);

   return mav;



이렇게 바꾸어 주도록 하자.


즉 ModelAndView에 두개의 오브젝트를 넣어서 넘기는 것이다.



그리고 다시 DownloadView 로 가서 


 fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");

  response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");


위의 코드를 아래와 같이 바꿔주도록 하자.


   File file2 = (File) model.get("realFileName");

String fileName="test";

try{

fileName = URLEncoder.encode(file2.getName(),"UTF-8").replaceAll("\\+", "%20");

}

catch(Exception e){

 fileName = URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");

}

 response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";");




이렇게 하면 끝! 완성! 해결!





+ Recent posts