나를 기록하다
article thumbnail
Published 2024. 3. 19. 08:55
[TIL-46/240318] File Upload & Download TIL
반응형

1. File Upload

1.1. 파일 업로드

  • 클라이언트가 서버로 파일을 전송하는 과정
  • 여러 개의 파일을 업로드 할 수 있음

 

1.2. 기존 방식의 Form

  • 기존에 사용하던 <form>은 문자 위주의 데이터를 사용
  • enctype="application/x-www-form-urlencoded" 기본 값(생략 가능)
  • HTTP Body에 문자로 key=value 형태로 전송하고, 여러 개의 데이터라면 & 기호를 통해 구분하였음

 

1.3. 파일 업로드 방식의 Form

  • 파일은 문자가 아닌 바이너리 데이터를 전송
  • 파일만 전송하는 것이 아니라 다른 데이터를 같이 전송하기도 함
  • enctype="multipart/form-data", method="POST" 필수
  • 여러 개의 파일을 업로드하고 싶다면 multiple="multiple" 속성 추가 필요

참고할 블로그

파일업로드 & 다운로드1

파일업로드 & 다운로드2

 

1.4. MultipartFile

  • Spring Framework에서 파일 업로드를 처리하기 위한 인터페이스
  • 파일의 내용은 메모리에 저장되거나, 디스크에 임시로 저장
  • 사용자가 원하는대로 세션수준 또는 영구 저장소에 파일의 내용을 복사할 책임
    • 세션 수준(Session Level): 웹 애플리케이션에서 데이터의 유효 범위를 나타내는 용어 중 하나입니다. 세션 수준은 데이터가 세션 동안 유지되는 기간
  • 임시 저장소는 요청이 끝나면 삭제
  • getOriginalFilename(): 업로드 파일명
  • transferTo(): 파일저장

 

1.5. 파일 업로드 추가 설정

  • servlet-context.xml 파일에 Multipart를 처리하기 위한 Resolver 등록
    • servlet-context: web과 관련된 정보 등록
  • StandardServletMultipartResolver → MultipartResolver의 구현체 중 하나 Spring MVC 권장
<bash />
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></beans:bean>
  • tomcat의 context.xml에서 allowCasualMultipartParsing="true"을 작성
  • 용량의 기본은 1MB / web.xml에서 용량을 지정 가능
<bash />
<multipart-config> <max-file-size>10485760</max-file-size> <max-request-size>20971520</max-request-size> </multipart-config>

 

2. 실습

2.1. controller

<java />
import java.io.File; import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; @Controller public class MainController { //파일이나 클래스 경로 등 리소스를 로드하는데 사용하는 인터페이스 private final ResourceLoader resourceLoader; @Autowired //생성자가 하나일 때는 @Autowired 생략 가능 public MainController(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } @GetMapping("/") public String index() { return "index"; } @GetMapping("/singleFileForm") public String singleFileForm() { return "singleFileForm"; } @PostMapping("/singleFileUpload") public String singleFileUpload(@RequestParam("file") MultipartFile file, Model model) throws IllegalStateException, IOException { //파일 있는지 검사, 용량이 없으면 등록하지 않겠다 if(file != null && file.getSize() > 0) { String fileName = file.getOriginalFilename(); System.out.println(fileName); Resource resource = resourceLoader.getResource("resources/upload"); file.transferTo(new File(resource.getFile(), fileName)); model.addAttribute("fileName", fileName); } return "result"; } @GetMapping("/download") public String download(@RequestParam("fileName") String fileName, Model model) { model.addAttribute("fileName", fileName); return "fileDownloadView"; } }

 

2.2. view

<java />
import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.FileCopyUtils; import org.springframework.web.servlet.view.AbstractView; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; public class FileDownloadView extends AbstractView { private final ResourceLoader resourceLoader; @Autowired public FileDownloadView(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; setContentType("application/download; charset=UTF-8"); } // 컨트롤러에서 뷰로 데이터를 전달하는 메서드 @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { String fileName = (String) model.get("fileName"); Resource resource = resourceLoader.getResource("resources/upload"); File file = new File(resource.getFile(), fileName); /////////////////////////////////////////////////////////// // 파일 다운로드 설정 response.setContentType(getContentType()); response.setContentLength((int) file.length()); fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1"); // 한글 방식을 안전하게 처리할 수 있게 해줌 response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";"); response.setHeader("Content-Transfer-Encoding", "binary"); //////////////////////////////////////////////////////////// try (FileInputStream fis = new FileInputStream(file); OutputStream os = response.getOutputStream()) { FileCopyUtils.copy(fis, os); } } }

 

2.3. WEB-INF/views

2.3.1. singleFileForm.jsp

<java />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>단일 파일 업로드</title> </head> <body> <h2>단일 파일 업로드</h2> <form action="singleFileUpload" method="POST" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="파일 등록"> </form> </body> </html>

 

2.3.2. multiFileForm.jsp

<java />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>다중 파일 업로드</title> </head> <body> <h2>다중 파일 업로드</h2> <form action="multiFileUpload" method="POST" enctype="multipart/form-data"> <input type="file" name="file" multiple="multiple"> <input type="submit" value="파일 등록"> </form> </body> </html>

 

2.3.3. result.jsp

<java />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>단일 파일 업로드</title> </head> <body> <h2>단일 파일 업로드</h2> <a href="${pageContext.request.contextPath }/resources/upload/${fileName}">${fileName }</a> <img src="${pageContext.request.contextPath }/resources/upload/${fileName}"> <a href="download?fileName=${fileName }">${fileName } 다운로드</a> </body> </html>

반응형

'TIL' 카테고리의 다른 글

[TIL-48/240320] DDL & DML  (0) 2024.03.21
[TIL-47/240319] MySQL, SELECT  (0) 2024.03.20
[TIL-45/240315] MVC 패턴  (0) 2024.03.16
[TIL-44/240314] Filter & Interceptor  (2) 2024.03.15
[TIL-43/240313] Spring MVC  (1) 2024.03.13
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!