Spring @RequestParam vs. @RequestPart
by 뚜부니API를 개발하다가 @RequestParam과 @RequestPart 차이가 갑자기 궁금하더라고요. 그래서 애노테이션 소스 코드를 열어봤는데 소스가 되게 비슷하더라고요..?! 🤔 이거 찾아봐야겠다 하는 생각이 들어서 찾아본 김에 정리해서 공유드려요 😊
1. 애노테이션 소스 코드 분석
먼저 애노테이션 소스 코드 분석을 해봤어요. 소스코드가 진짜 비슷하게 생겼거든요. 아마 이거 먼저 보시면 '엇..? 이게 뭐지?' 하는 생각이 드실 수도 있어요. 참고로, 공통 메타 애노테이션인 @Target, @Retention, @Documented 설명은 생략하고 소스만 분석했어요.
1.1. @RequestPart 소스 코드
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestPart {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
}
- value와 name
- @AliasFor("name") 또는 @AliasFor("value") 라고 되어 있는 것은 서로 같은 속성을 가리킨다는 의미입니다.
- 즉, value를 설정하면 내부적으로 name이 같은 값으로 설정되며, name을 설정하면 value가 동일하게 설정됩니다.
- e.g.) @RequestPart("file")와 @RequestPart(name = "file")는 동일하게 동작합니다.
- required
- 기본 값은 true로, 해당 파라미터에 반드시 요청이 포함되어야 함을 뜻합니다.
1.2. @RequestParam 소스 코드
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
- value와 name, required는 @RequestPart와 동일합니다.
- defaultValue
- 파라미터가 없거나 빈 문자열로 넘어왔을 때 해당 값이 기본 값으로 설정됩니다.
- 소스 코드에 보이는 "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"는 특별한 문자열(센티넬 값)로, 사용자가 defaultValue를 지정하지 않았음을 구분하기 위한 내부 처리용입니다.
- e.g.
@GetMapping("/search")
public String search(
@RequestParam(defaultValue = "Spring") String keyword
) {
// keyword 파라미터가 없으면 "Spring"이 기본값으로 매핑
return "결과";
}
내부 애노테이션만 보면 유사한데, 사용하는 목적이나 데이터 변환 방식에 차이가 있는 것 같더라고요. 어떤 특징을 가지는지 하나씩 좀 더 자세하게 살펴볼게요.
2. @RequestParam
@RequestParam은 별도 설정 없이 문자열, 숫자 등의 자동 변환이 이뤄지고, key-value 형식에 쉽게 매핑할 수 있어요.
@GetMapping("/search")
public String search(@RequestParam String keyword) {
// ?keyword=Hello 와 같은 파라미터를 쉽게 매핑
return "결과";
}
@RequestParam은 주로 다음과 같은 상황에 사용해요.
- 쿼리 파라미터(Query Parameter): 예) ?keyword=Spring
- Form Data: 전형적인 application/x-www-form-urlencoded 형식
- 파일이 아닌 단순 텍스트 필드: multipart/form-data에서 파일을 제외한 다른 필드
3. @RequestPart
@RequestPart는 Multipart 형식에서 파일뿐만 아니라, JSON이나 일반 텍스트도 파트 단위로 분리해 매핑하며, 내부적으로 HttpMessageConverter를 통해 변환이 이뤄지므로, JSON DTO로 매핑하는 것도 가능해요.
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String upload(
@RequestPart("file") MultipartFile file,
@RequestPart("metadata") String metadata
) {
// 파일 파트와 메타데이터(문자열 혹은 JSON)를 각각 별도의 파라미터로 매핑
return "업로드 성공";
}
@RequestPart는 주로 multipart/form-data 형식에서 파일 업로드나 JSON/텍스트 등 복합 데이터를 "파트(part)" 단위로 받는 경우 사용해요.
4. @RequestParam vs. @RequestPart 차이점 정리
@RequestParam과 @RequestPart에 대한 차이점을 좀 더 눈에 잘 들어오게 표로 정리해 봤어요.
@RequestParam | @RequestPart | |
주 사용 목적 | - Query Parameter - Form Data (x-www-form-urlencoded) - Multipart의 단순 텍스트 필드 |
- Multipart/Form-Data 내 파일 업로드 - Multipart/Form-Data 내 JSON, 텍스트 (파트 단위) |
HTTP 요청 형식 | - 일반 쿼리 스트링 파라미터 또는 폼 데이터 | - multipart/form-data |
데이터 변환 | - 주로 단순 String, Number 변환 - 필요하면 Converter 이용 가능 |
- HttpMessageConverter를 통해 파일, JSON 등 복합 형식 처리 가능 |
주 사용 예시 | - @RequestParam("keyword") String keyword | - @RequestPart("file") MultipartFile file - @RequestPart("jsonData") DTO dto |
참고
- https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/requestparam.html
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestPart.html
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
'Spring' 카테고리의 다른 글
Spring Boot, MongoDB 프로젝트 네이밍 설정 방식 (0) | 2024.12.06 |
---|---|
Kotlin + Spring 프로젝트 MongoDB 설정 (0) | 2024.11.30 |
Spring 프로젝트 내부에 React 설정 및 Build (Gradle) (0) | 2023.01.15 |
Spring DI (0) | 2022.11.27 |
properties로 Spring Boot log를 설정해보자! (0) | 2022.04.23 |
블로그의 정보
개발하는 두부
뚜부니