7/16, 7/17 스프링 파일 업로드(MultipartFile)

박세현·2024년 7월 16일

Spring

목록 보기
12/15
post-thumbnail

스프링 파일 업로드(MultipartFile)

1. multipart란?

<form> 속성 : enctype="multipart/form-data"

  • multipart

    • 일반 양식 데이터의 파트
    • 파일 데이터(바이너리 데이터) 파트
  • 기본 양식 content-type

    • application/x-www-form-urlencoded



2. web.xml 설정

<multipart-config>
	<max-file-size>20971520</max-file-size> <!--  1MB * 20 --> // 한 파일당 최대 올릴 수 있는 용량 설정
    <max-request-size>41943040</max-request-size> <!-- 40MB --> // 
</multipart-config>
  • 파일 업로드 설정
    • 파일용량을 보통 설정
    • 한파일당 최대용량 정의
    • 전체 파일용량 설정
  • 파일 업로드 -> 서버쪽 임시 폴더에 파일이 만들어짐 -> 이걸 실제 서버 경로로 파일을 옮김
  • 파일요청이 오면 실제 요청데이터를 파일데이터 와 양식데이터로 분리
  • 파일데이터를 분리해서 임시로 보관
    • 램 메모리에 임시보관하는데 (그리고 서버의 특정 경로로 옮김)
    • threshold 용량을 넘어면 임시 폴더에 파일을 임시저장하고 서버의 특정 경로로 옮김

  • bit : 8
  • 1byte : 8비트
  • 1kbyte : 1024바이트
  • 1mbyte : 1024키로바이트

  • ex) 20mb : 1024 1024 20 -> 20mb

예시) 파일업로드

ㄴ 파일명만 전송된 형태

ㄴ 파일명만 전송된 형태

ㄴ 멀티파트 폼 데이터



1) @RequestPart

  • @RequestPart는 HTTP 요청에서 multipart/form-data로 전송된 특정 파트(part)를 메서드 매개변수로 바인딩할 때 사용됩니다. 주로 파일 업로드나 복잡한 JSON 데이터와 같은 구조화된 데이터를 처리할 때 사용됩니다.

  • 사용 상황
    • 파일 업로드: 클라이언트가 파일을 전송할 때 MultipartFile 객체로 바인딩할 수 있습니다.
    • 복잡한 JSON 데이터: 요청의 일부로 전송된 JSON 데이터를 특정 객체로 바인딩할 수 있습니다.

예시) 파일 업로드 처리 + JSON 데이터 처리

  • 파일 업로드 처리
@PostMapping("/upload")
public String handleFileUpload(@RequestPart("file") MultipartFile file) {
    return "Uploaded file: " + file.getOriginalFilename();
}

클라이언트가 파일을 multipart/form-data로 전송하면, 해당 파일이 MultipartFile 객체로 바인딩됩니다.

  • JSON 데이터 처리
@PostMapping("/submit")
public String submitData(@RequestPart("info") UserInfo info) {
    return "Received user: " + info.getName();
}

public static class UserInfo {
    private String name;
    private int age;

    // getters and setters
}

클라이언트가 info라는 이름으로 JSON 데이터를 전송하면, 이 데이터가 UserInfo 객체로 바인딩됩니다.

  • 특징
    • @RequestPart는 주로 파일 및 구조화된 데이터(JSON 등)를 처리하는 데 사용됩니다.
    • multipart/form-data 요청에서 특정 파트를 처리하기 위한 애노테이션입니다.


번외) @RequestParam

  • @RequestParam은 HTTP 요청의 쿼리 매개변수, 폼 데이터, 또는 URL의 경로 변수 값을 메서드 매개변수로 바인딩할 때 사용됩니다.

  • 사용 상황

    • 쿼리 매개변수: GET 요청의 쿼리 스트링에서 값을 가져올 때 사용됩니다.
    • 폼 데이터: POST 요청에서 전송된 폼 데이터를 처리할 때 사용됩니다.

번외 예시) @RequestParam

  • 쿼리 매개변수 처리
@GetMapping("/search")
public String search(@RequestParam("query") String query) {
    return "Search results for: " + query;
}

클라이언트가 http://example.com/search?query=spring으로 요청을 보내면, query 매개변수의 값인 "spring"이 메서드의 query 파라미터로 바인딩됩니다.
폼 데이터 처리

@PostMapping("/submit")
public String submit(@RequestParam("name") String name, @RequestParam("age") int age) {
    return "Name: " + name + ", Age: " + age;
}

클라이언트가 POST 요청으로 name과 age 값을 전송하면, 해당 값들이 메서드 파라미터로 바인딩됩니다.

  • 특징
    • @RequestParam은 주로 단순 텍스트 데이터(문자열, 숫자 등)를 처리하는 데 사용됩니다.
    • 필드가 필수인지, 기본값이 있는지 등을 설정할 수 있습니다.
    • @RequestParam(value = "name", required = false, defaultValue = "Guest")


번외) @RequestParam vs @RequestPart

  • 데이터의 출처

    • @RequestParam: 쿼리 매개변수, 폼 데이터, URL 경로 변수 등 단순 텍스트 데이터를 처리합니다.
    • @RequestPart: multipart/form-data 요청의 특정 파트를 처리하며, 주로 파일과 JSON 데이터를 다룹니다.
  • 사용되는 컨텐츠 타입

    • @RequestParam: 보통 application/x-www-form-urlencoded나 multipart/form-data에서 폼 필드에 대한 값을 처리합니다.
    • @RequestPart: multipart/form-data 요청에서 파일이나 JSON 데이터를 처리합니다.
  • 복잡한 데이터 구조

    • @RequestParam은 기본적으로 문자열, 숫자 등 단순한 데이터 타입을 처리하며, JSON이나 파일 같은 복잡한 데이터 구조를 처리하는 데는 적합하지 않습니다.
    • @RequestPart는 복잡한 JSON 객체나 파일과 같은 다중 파트 데이터를 처리할 수 있습니다.
  • 요약

    • @RequestParam: 단순한 요청 파라미터 값을 처리하는 데 사용되며, 주로 쿼리 스트링이나 폼 데이터를 처리합니다.
    • @RequestPart: multipart/form-data 요청에서 특정 파트를 처리하며, 파일 업로드나 복잡한 JSON 데이터를 처리하는 데 사용됩니다.



3. MultipartFile 인터페이스

  • 애를 요청데이터에 주입하면 파일을 바로 업로드 할 수 있음
  • @RequestPart : 어떤 이름으로 넘어오는지 알려주기

  • 동일 이름의 여러 파일을 전송하는 경우?
    MultipartFile[] 와 같은 배열로 주입

  • getBytes() : 파일을 byte형식으로 가져오기
  • getContentType() : 파일 형식
  • getName() : <input type='file' name='이름'> 에서 name값을 가져오는 것
  • getOriginalFilename() : 원래파일명? -> db에 이 이름 사용
  • trasferTo() : 임시폴더나 램에 있는 파일을 실제 파일경로에 옮기기

Interface MultipartFile
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/MultipartFile.html

ㄴ getBytes() : 파일을 byte형식으로 가져오기
ㄴ getContentType() : 파일 형식

ㄴ 양식에 있는 name값
ㄴ getName() : <input type='file' name='이름'> 에서 name값을 가져오는 것

ㄴ getOriginalFilename() : 원래파일명?

ㄴ trasferTo() : 임시폴더나 렘에 있는 파일을 실제 파일경로에 옮기기


예시) getOriginalFilename()

  • 원래파일명? -> db에 이 이름 사용



예시) trasferTo()

  • 임시폴더나 램에 있는 파일을 실제 파일경로에 옮기기



예시) FileConfig + MvcConfig

파일업로드 경로가 바귈수 있으니

ㄴ 파일 정적경로 설정함

ㄴ static 형태로 정의 왜...?
ㄴ 플레이스홀더 : 교체하는 방식으로 설정하겠다
ㄴ 설정방식을 의미 : 플레이스 홀더

ㄴ 설정파일 여러개 사용 시 ...짜리 메서드 사용

ㄴ $ 있는 부분 : 플레이스 홀더

ㄴ 주입되는 값 전부 문자열

ㄴ 이 값을

ㄴ 여기 대입



예시) 파일 업로드

ㄴ 정적경로도 잘 동작함




4. addResourceHandlers 설정

  • 파일 업로드 경로 -> 서버 접근 URL로 연결





프로필

1. @Profile




2. spring.profiles.active

  • 환경변수
  • 여기에 지정된 환경변수 값을 가지고 @Profile에 설정 시 @Bean을 프로필에 따라서 달리 생성하는 기능

ㄴ deq(개발시 설정)

ㄴ prod(배포시 설정)



1) web.xml

<init-param>
  <param-name>spring.profiles.active</param-name>
  <param-value>dev</param-value>
<init-param>

ㄴ 근데 매번 xml파일에서 바꿔주는거 넘 비효율적

ㄴ 이거 환경변수 바꿔주는게 더 편함

ㄴ 잘 나옴

ㄴ 이거 문제 있음
ㄴ 해킹의 문제
ㄴ 계정을 공유하는것은 보안적으로 중요하지 않음
ㄴ 내 실제 서버 계정을 올리면 깃허브에 올리면 해킹을 당함
ㄴ 로컬이든 실제 서버계정이든 모든 다 깃헙에 오리면 안됨
ㄴ 절대로 이런 계정을 올리면 안됨
ㄴ 환경변수를 이용하는게 좋음

ㄴ 다시 db설정 돌림
ㄴ db설정은 실행과정중에 설정하는게 좋음
-> 환경변수를 이요하는게 좋음



2) 배포 파일 실행시

  • java -jar -Dspring.profiles.active=프로필이름


3) 환경변수를 조회하는 방법

  • System.getEnv("환경 변수명")

ㄴ 이런방식으로 해야함
ㄴ db계정은 절대 오픈소스에 올리면 안됨

예시)

ㄴ 이거 이대로 올리면 맥(리눅스)은 오류 뜸
ㄴ + 나 노트북에 d드라이브 없는데
ㄴ 근데 이 설정을 가지고 다같이 작업해야하는데 누구는 맥이고 누구는 윈도우이면 우짬
ㄴ 다들 설정이 다르다 -> 그럼 환경변수에 따라 설정을 다르게 적용해줘야지
ㄴ 프로파일 통해 설정 분리하자

ㄴ 프로파일 통해 설정파일 분리함

ㄴ 이런식으로

ㄴ 설정 2개 생성

ㄴ 설정파일에 따라 다르게 업로드됨

ㄴ uploads1이 아닌 uploads2 에 생성된 모습 쳌

ㄴ 이거 는 개발환경마다 다르니 깃 이그노어해야함
ㄴ 안그럼 다른 사람 작업 망가짐...





프로퍼티 파일을 이용한 프로퍼티 설정

1. @Configuration

public static PropertySourcesPlaceholderConfigurer properties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		configurer.setLocations(
				new ClassPathResource("db.properties"),
				new ClassPathResource("info.properties"));
		return configurer;
}



2. @Value("${프로퍼티 키값}")

profile
귤귤

1개의 댓글

comment-user-thumbnail
2024년 7월 17일
  1. MultipartFile 인터페이스 부터 시작~
답글 달기