🐯
경민민 IT 핸드북
  • Orientation
    • 전달사항
    • 복습방법
    • 수료한 선배의 한마디
    • 간단 자기소개
    • 스터디
  • 백엔드
    • Java
      • 1장 프로그래밍 기초
      • 2장 자바 메모리구조
        • 1. Stack
        • 2. Heap
      • 6장 객체
      • 8장 상속
      • 9장 다형성
      • 10장 추상클래스와 인터페이스
      • 13장 Generic
      • 14장 Thread
      • 15장 Network
      • 16장 Lamda
        • 1. 내부 클래스 (Inner Class)
          • DTO , VO, Builder Pattern
        • 2. 람다 표현식 (Lambda Expression)
        • 3. 스트림 API (Stream API)
          • Optional
      • 17장 Enum
  • 프론트
    • Node.js
    • Java Script
      • ES6+
        • Node.js로 자바스크립트 실행
        • let , const , var
        • Destructuring문법
          • Rest(...) 문법
        • Arrow Function
        • 모듈
        • ETC
    • Type Script
      • 개요
      • TS설치 및 환경설정
      • 타입스크립트 기본
        • 기본 자료형들과 타입추론
        • Object, Array , Tuple
        • Any, Unknown, Union Type
        • Function Type
          • Type Assertion && Narrowing
          • Never type
        • Type Aliases와 Interface
        • 리터럴 타입
        • 함수 추가 문법
        • Class문법
        • 객체 타입 추가 문법
        • 실습문제 1차
        • 실습문제 2차
        • 실습문제 3차
    • React
      • 개요
      • SPA 와 MPA
        • SEO(작성예정)
      • 리액트 프로젝트 생성(18.3.1.ver)
        • HTML + react 샘플
        • CRA 와 Vite 비교
      • 리액트 개념들
        • Component
          • 클래스 컴포넌트(작성예정)
          • 함수형 컴포넌트(작성예정)
        • JSX
        • React Virtual Dom
          • Reconciliation
        • hook
          • useState
        • 리액트 데이터 전달
          • FLUX
      • 백엔드 서버 연동
        • 비동기요청
        • 웹소켓
        • Promise(작성예정)
      • 실습문제 1
      • 실습문제 2
      • 실습문제3
      • 실습문제4
  • 프레임워크
    • Spring
      • Spring 개발환경 구축
        • 프로젝트 환경설정
        • 프로젝트 생성
          • MVC Project 생성이슈
        • Maven 설정
        • web.xml 설정
        • Spring Bean Configuration.xml 설정
      • Spring Legacy Project
        • Spring 요청 및 응답 흐름
        • Spring 주요 Annotation
          • 의존성 주입방식의 차이점
          • @ModelAttribute와 유효성검사
          • 비동기처리
          • 스프링 예외처리
        • Logging
        • Pagination
        • Spring File 업로드 및 다운로드
        • Spring WebSocket
        • Spring AOP
      • Spring 라이브러리들(작성예정)
        • Lombok
        • Maven
        • MyBatis
      • Spring 구성 모듈(작성예정)
      • 스프링 과제
    • Spring Boot
      • Spring Boot 개발환경 구축
      • 스프링 부트 프로젝트 생성방법들
        • 프로젝트에서 사용하는 의존성들
      • 스프링 프로젝트 구조
        • SpringBootApplication
      • application.properties
      • Cross Origin
        • CORS
      • WebSocket
        • Stomp(작성중)
      • 로그인(작성중)
      • Spring Security(작성중)
      • 실습문제 Select
      • 실습문제 Update
      • 실습문제 Delete
  • 형상관리(Git)
    • GitHub설정
    • SourceTree를 활용한 깃허브 연동
      • 소스트리 설치
      • Clone
      • Branch
        • Branch Protection rules
          • Branch Protection Rules 상세규칙
        • Rebase 와 Squash (작성예정)
      • Team Project 설정
        • 팀장 프로젝트 셋팅
          • Collaborator
          • .gitignore 설정
        • 팀원 프로젝트 셋팅
        • 공통 프로젝트 진행
  • 프로젝트
    • 진행순서
      • 요구사항 분석 단계
        • 유용한 사이트
      • 프로그램 설계 단계
        • 유용한 사이트
      • 프로그램 구현단계
        • SourceTree를 활용한 Team Project설정
      • 테스트 단계
  • 배포
    • AWS-EC2 배포 연습
    • DevOps
      • IT시스템의 변화와 DevOps
      • DevOps 라이프사이클
    • 젠킨스
      • 도커
        • 도커 설치 방법
        • 도커 기본 명령어들
      • 젠킨스 설치
      • 젠킨스 프로젝트 생성
      • 젠킨스 소스코드 통합 - Github
      • 젠킨스 빌드 설정 - Maven
      • 배포 서버 구축하기
      • 파이프라인 구축
      • AWS 서버 생성
        • AWS 인스턴스 생성
        • AWS - Zenkins 연동
        • AWS - 배포서버 연동
        • AWS - Jenkins CI/CD파이프라인 구축
  • 유용한 사이트 모음
  • SQL
    • SQLD
      • 데이터 모델링의 이해 - 스키마
      • 데이터 모델링의 이해 - ERD
      • 데이터 모델링의 이해 - 정규화
      • 데이터 모델링의 이해 - NULL
      • SQL 기본 및 활용 - WINDOW FUNCTION
    • Oracle
      • 1장 개요
      • 2장 SQL
  • LLM 서비스
    • 1장 LLM에 대한 이해
    • 2장 프롬프트 엔지니어링
      • 프롬프트와 프롬프트 엔지니어링
      • GPT PlayGround
      • 프롬프트 작문 유형
      • 기본 프롬프트 엔지니어링 태크닉
      • 고급 프롬프트 엔지니어링 태크닉
        • ReAct Prompting
        • Active-Prompt
        • Reflexion
        • Graph Prompt
      • OpenAI API설정
      • OpenAI를 활용한 프롬프트 엔지니어링 실습
        • 실습 프롬프트
    • 3장 Lang Chain 프레임워크
      • LangSmith 프레임워크
        • LangSmith를 활용한 LangChain 모니터링 설정
      • LangChain 실습 1 - Prompt
        • 실습 코드
      • LangChain 실습 2 - LLM 캐시와 메모리
    • 4장 RAG
      • Document Loader - 문서 로더
      • Text Splitter - 텍스트 분할
      • Embedding - 임베딩
      • Vector Store - 벡터 저장소
      • Retriever - 검색기
      • ReRanker - 재평가자
      • RAG
Powered by GitBook
On this page
  • Multipart
  • Multipart방식의 요청을 처리하기 위한 설정(파일 업로드)
  • 1) pom.xml설정
  • 2) root-context.xml
  • 3) HTML설정
  • 4) Controller 설정
  • 5) 파일시스템에 파일 저장
  • 6) 저장이후
  • 파일 다운로드
  • 스프링 파일 다운로드 기능 요청 흐름
  • 클라이언트의 File Down요청
  • 서버의 File Down로드 처리 Handler
  • ResouceLoader를 활용한 File load
  • ResponseEntity를 활용한 File 응답
  • ResponseEntity
  1. 프레임워크
  2. Spring
  3. Spring Legacy Project

Spring File 업로드 및 다운로드

PreviousPaginationNextSpring WebSocket

Last updated 10 months ago

Multipart

  • Multipart란 파일업로드시 사용하는 enctype으로 , 하나의 요청에 대해 데이터를 전달하기 위한 공간을 여러개의 파트로 나눈 후 나눈 공간에 각 각의 데이터를 저장하여 요청을 보내는 기법이다.

  • Multipart는 전달할 수 있는 데이터 타입에 File과 같은 바이너리 데이터를 저장하여 요청을 보낼 수 있어서 파일 업로드시 사용된다.

form태그의 기본 enctype은 application/x-www-form-urlencoded 이다.

이 설정은 text형태의 문자열데이터만 전달이 가능하며 바이너리데이터 전송을 지원하지 않는다. 따라서 파일업로드 기능을 이용하려면 form태그의 enctype을 multipart방식으로 수정해줘야한다.

<form enctype="multipart/form-data" >

input:file, input:text등 사용 가능

</form>

  • 스프링의 매개변수 자동 데이터 바인딩 기능은 Multipart방식으로 들어온 요청에 대한 바인딩처리는 기본설정으로 지원하지 않는다.

  • 스프링은 위와 같은 multipart방식의 요청을 처리하기 위한 클래스로 MultipartResolver라는 인터페이스를 제공하고 있으며 수업에서는 해당 인터페이스를 구현한 다양한 의존성 중 보편적으로 많이 사용되는 CommonsMultipartResolver 의존성을 통해 파일 업로드 기능을 구현할 것이다

Multipart방식의 요청을 처리하기 위한 설정(파일 업로드)

1) pom.xml설정

  • CommonsMultipartResolver사용을 위한 구현체 추가

-- pom.xml파일 내부 --
<!-- 1) commons-fileupload
        파일 업로드를 위한 의존성(CommonsMultipartResolver 구현체)
-->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

<!-- 2) commons-io  
        파일 다운로드를 위한 의존성 
-->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

2) root-context.xml

  • multipartResolver 빈 객체추가

<!-- 스프링 컨테이너는 Multipart요청 처리시  bean id 기준으로 multipartResolver라는 이름의
     객체가 존재하는지 찾는다. 이때 bean의 id에 오타가 있을 경우 multipartResolver가 없다고
     생각하고 프로세스가 진행되므로 "정확히" 타이핑해야한다. -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 	<!--  인코딩 처리 -->
 	<property name="defaultEncoding" value="UTF-8"></property>
 	<!-- 
 		maxUploadSize : 한번에 업로드 되는 파일의 총 용량 설정 
 		maxInMemorySize : 디스크에 임시파일을 생성하기전에 메모리에 보관시킬 
                                  최대 바이트 크기. 이 크기를 벗어나면 드라이브에 보관한다.
 	 -->
 	 <property name="maxUploadSize"   value="10000000"></property>
 	 <property name="maxInMemorySize" value="10000000"></property>
 </bean>

3) HTML설정

<!--  enctype에 오타가 나지 않게끔 조심할것 -->
<form action="insert" method="post" enctype="multipart/form-data">
    <input type="file" name="upfile">
</form>

4) Controller 설정

@PostMapping("/insert")
public String insertBoard(
	@RequestParam(value="upfile" , required = false ) MultipartFile upfile , 
	) {
  • dispatcherServlet은 클라이언트의 요청이 multipart/form-data인 경우 MultipartResolver를 통해 요청 내용을 파싱한다.

  • 파싱은 HttpServletRequest객체를 MultipartRequest객체로 변환시키는 과정을 의미하며 MultipartRequest는 HttpServletRequest을 상속받아 파일 업로드에 대한 기능만 추가한 클래스이다.

  • 파싱과정이 완료되면 서버는 전달받은 파일객체를 메모리에 임시 보관해 두었다가@RequestParam(value="upfile" , required = false ) MultipartFile upfile 에 보관중인 파일객체를 전달해준다. (MultipartFile은 http통신으로 전송된 파일을 처리하기위한 객체로 다양한 메서드를 가지고 있다)

5) 파일시스템에 파일 저장

  • 파일저장은 메모리에 4번과정에서 얻어온 MultipartFile 객체를 통해서 진행될 것이며 , 저장시키기 위해서는 저장하고자하는 디렉토리 경로와 저장할 파일명이 추가로 필요하다.

  • 디렉토리 경로는 정해진 규칙에 따라 작성하면 될것이다. EX) 게시판의 이미지를 저장하는 URL -> 프로젝트경로/resources/images/게시판/

  • 저장할 파일명은 디렉토리 내에서 겹치지 않는 고유한 이름이 들어갈 수 있도록반드시 변경해줘야 한다. (하나의 디렉토리에 동일한 이름으로 파일이 들어가게 된다면 에러가 발생하기 때문)

//파일 저장 메서드
//MultipartFile의 transferTo 메서드를 통해 메모리에 보관중인 데이터를 파일 시스템의 드라이브로
//이동시킨다. 매개변수로는 디렉토리경로(마지막 위치에 /가 포함된) + 저장할 파일명이 들어간다.
upfile.transferTo(new File(디렉토리경로+저장할 파일명));

MultipartFile의 주요 메서드

반환형 메서드명
설명

String getName()

파라미터로 전달된 이름

String getOriginalFilename()

업로드 되는 파일의 이름

boolean isEmpty()

파일이 존재하는지 여부

long getSize()

업로드되는 파일의 크기

byte[] getBytes()

byte[]로 파일 데이터 반환

inputStream getInputStream()

파일데이터와 연결된 inputStream을 반환

transferTo(File file)

파일저장

6) 저장이후

  • 서버의 파일시스템상에 첨부파일이 잘 등록 되었다면 핵심 업무로직에 맞춰서 비지니스 로직을 구상하면 된다. 보편적으로는 저장된 데이터를 관리하기 위해 db에 값을 기록해둘 것이다.


파일 다운로드

스프링 파일 다운로드 기능 요청 흐름

  1. 클라이언트가 File Down요청을 보낸다

  2. 요청을 처리할 컨트롤러의 Handler(메서드)는 클라이언트의 요청시 전달한 데이터를 바탕으로 어플리케이션에서 적절한 file을 load한다.

  3. load한 파일을 클라이언트에게 출력스트림을 이용하여 직접 응답한다.

  • 위 처리 흐름에서 주목할 점은 클라이언트에게 File을 직접 응답하는 부분이다. Spring Mvc 프로젝트는 View Resolver가 클라이언트의 응답화면 처리를 담당하는데 이를 무시하고 클라이언트에게 바로 파일을 전달하는게 포인트이다.

클라이언트의 File Down요청

<H1>첨부파일</h1>
<button type="button"
onclick="location.href='${contextPath}/board/fileDownload/${board.boardNo }'">
	${board.originName} - 다운로드
</button>
// 다운로드 받고자 하는 정보를 URL로 전달

서버의 File Down로드 처리 Handler

  • 클라이언트가 요청한 파일을 검색

@GetMapping("/fileDownload/{boardNo}")
public ResponseEntity<Resource> fileDownload(@PathVariable("boardNo") int boardNo) {
	ResponseEntity<Resource> responseEntity = null;
	// db에서 board테이블에서 boardNo값과 일치하는 행의 파일정보 조회
	BoardExt b = boardService.selectBoard(boardNo);
	// 파일이 없는경우 응답상태 404로 설정후 반환
	if(b.getOriginName() == null) {
		return responseEntity.notFound().build();
	}
	...
}

ResouceLoader를 활용한 File load

ResouceLoader?

ResponseEntity를 활용한 File 응답

ResponseEntity

Multipart Request 예시