업로드

스프링에서 파일을 업로드 하는 방법에는 여러가지가 있다. 1번인 MultipartFile의 경우를 가장 많이 사용한다.

  1. MultipartFile 사용
    public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
          if (!file.isEmpty()) {
             String filename = file.getOriginalFilename();
             ...
          }
     }
    
  2. MultipartHttpServletRequest 사용
    public String fileUpload(MultipartHttpServletRequest request) throws IOException {
    MultipartFile file = request.getFile("file");
          if (!file.isEmpty()) {
             String filename = file.getOriginalFilename();
             ...
          }
     }
    

Front-end

  • form 태그에 enctype="multipart/form-data" 사용
  • input 태그에 type="file" 사용
<form name="docsForm" method="post" enctype="multipart/form-data">
   <input type="text" name="title">
   <input type="text" name="content">
   <input type="file" name="file">
</form>

Back-end

  • MultipartFile 사용
  • getOriginalFilename() : client가 첨부한 파일명 출력(확장자포함)
  • transferTo(File file) : 해당 경로로 파일 전송
public String fileUpload(@RequestParam("file") MultipartFile file) {
   if (!file.isEmpty()) {
      String originalName = file.getOriginalFilename();      // 본래 파일명(original.jpg)
      String extension = originalName.substring(originalName.lastIndexOf("."), fileName.length());             // 확장자 추출(.jpg)
      String url = "/Users/europani/file/";                 // 폴더 경로

      UUID uuid = UUID.randomUUID();                        // 새로운 파일명에 쓸 난수 생성(abcedf)
      String fileName = uuid.toString() + extension;        // 새로운 파일명(abcedf.jpg)
      
      File saveFile = new File(url, fileName);              // 경로명:/Users/europani/file/abcedf.jpg
      try {
         file.transferTo(saveFile);
      } catch (IOException e) {
         e.printStackTrace();
      }

      FileVO fileVO = new FileVO();
      fileVO.setUrl(url);
      fileVO.setFileName(fileName);
      fileVO.setOritinalName(originalName);

      // ...DB에 저장...
   }
}

다운로드

Front-end

<table>
   <tr>
      <th>
         <label for="file">첨부파일</label>
      </th>
      <td>
         <th:block th:each="file : ${files}">
            <a th:href="@{/request/fileDown(id=${file.id})}" th:text="${file.originName}"></a>
         </th:block>
      </td>
   </tr>
</table>

Back-end

  • HttpServletResponseResponseEntity를 사용 하는 2가지 방법이 있다
  • ResponseEntity 를 통한 방법을 사용할 것이다
public ResponseEntity<Resource> fileDownload(@RequestParam Long id, HttpServletRequest request) throws IOException {
   // ... id를 사용하여 DB로부터 파일 정보 get...

   File file = new File(fileVO.getUrl() + fileVO.getFileName());
   String fileName = "";

   // IE여부 판별하여 fileName 설정
   String userAgent = request.getHeader("User-Agent");
   boolean ie = (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident") > -1);

   if (ie) {
      fileName = URLEncoder.encode(fileVO.getOriginName(), "utf-8").replaceAll("\\+", "%20");
   } else {
      fileName = new String(String.valueOf(fileVO.getOriginName()).getBytes("utf-8"), "iso-8859-1");
   }

   // 헤더 설정
   HttpHeaders header = new HttpHeaders();
   header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
   header.add("Cache-Control", "no-cache, no-store, must-revalidate");
   header.add("Pragma", "no-cache");
   header.add("Expires", "0");

   // 바디 설정(파일)
   InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

   return ResponseEntity.ok()
                .headers(header)        // 헤더 삽입
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(resource);        // 바디 삽입
}