쿼리 파라미터(Query Parameter)
📌 HTTP 요청 URL의 일부로, Key-Value 형태로 데이터를 전달하는 방법
- 쿼리 파라미터는 URL 경로 끝에 **?**로 시작하며, 여러 개의 파라미터는 **&**로 구분됩니다.
구조
<URL>?<key1>=<value1>&<key2>=<value2>
특징
- 클라이언트가 서버로 데이터를 전달할 때 사용.
- GET 요청에서 주로 사용되며, 요청 URL에 데이터를 포함.
- 데이터가 URL에 노출되므로 민감한 정보를 보내는 데 적합하지 않음.
- 여러 파라미터를 전달할 수 있음.
HTML 폼 데이터(Form Data)
📌 HTML 폼(Form)을 통해 서버로 전달되는 Key-Value 형태의 데이터입니다.
- 폼 데이터는 주로 POST 요청의 HTTP 요청 본문(body)에 포함됩니다.
구조
HTML 폼을 통해 데이터를 보낼 때, Key-Value 쌍으로 데이터를 전달합니다. 데이터는 HTTP 요청 본문에 포함되거나, GET 요청의 경우 쿼리 파라미터로 전송됩니다.
특징
- POST 요청에서 주로 사용되며, 데이터가 HTTP 요청 본문에 포함.
- GET 요청에서는 폼 데이터가 쿼리 파라미터로 전달.
- 데이터를 숨길 수 있으나, 민감한 데이터는 암호화(HTTPS) 필요.
- 주로 사용자 입력 데이터를 서버로 전달할 때 사용.
HTML 폼 예제
<form action="/submit" method="POST">
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<button type="submit">Submit</button>
</form>
POST 요청 본문 예시:
name=John&email=john.doe@example.com
Spring 컨트롤러에서 처리:
@PostMapping("/submit")
public String handleForm(
@RequestParam String name,
@RequestParam String email) {
return "Name: " + name + ", Email: " + email;
}
쿼리 파라미터와 폼 데이터의 차이
쿼리 파라미터 (Query Parameter) | HTML 폼 데이터 (Form Data) | |
데이터 위치 | URL 경로 끝 (쿼리 스트링) | HTTP 요청 본문(body) 또는 URL 쿼리 |
주요 HTTP 메서드 | GET | POST (또는 GET) |
노출 여부 | 데이터가 URL에 노출됨 | POST 요청 시 URL에 노출되지 않음 |
사용 목적 | 짧고 간단한 데이터 전달 | 사용자 입력 데이터 전송 |
데이터 크기 제한 | 브라우저에 따라 URL 길이 제한 (2,000~8,000자) | 요청 본문에 데이터를 보내므로 제한 없음 |
보안성 | 민감한 데이터 전달에 부적합 | POST로 전달 시 상대적으로 안전 (HTTPS 권장) |
예제 비교
쿼리 파라미터
GET /search?keyword=spring&category=books
폼 데이터
POST /submit
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
name=John&email=john.doe@example.com
결론
- 쿼리 파라미터는 주로 GET 요청에서 사용되며, URL에 간단한 데이터를 전달.
- 폼 데이터는 주로 POST 요청에서 사용되며, 대량의 사용자 입력 데이터를 서버로 보낼 때 적합.
@RequestParam
📌 HTTP 요청의 쿼리 파라미터(Query Parameter)나 HTML 폼 데이터(Form Data)를 컨트롤러 메서드의 매개변수로 매핑하는 데 사용됩니다. 주로 클라이언트가 요청 시 전달하는 Key-Value 형식의 데이터를 처리할 때 사용됩니다.
- URL에서 파라미터 값과 이름을 함께 전달하는 방식으로 주로 HTTP 통신 Method 중 GET 방식의 통신을 할 때 많이 사용한다. @Requestparam을 사용하면 요청 파라미터 값에 아주 쉽고 간편하게 접근(Parameter Binding)할 수 있습니다.
- ?뒤에 오는 URL을 Query String, Query Parameter, Request Param이라 합니다.
- GET 요청에서 쿼리 파라미터를 처리하거나, POST 요청에서 폼 데이터를 처리하는 데 사용됩니다.
사용 목적
- 쿼리 파라미터(Query Parameter):
- URL에 포함된 Key-Value 형식의 데이터를 매핑.
- 예: GET /api/search?keyword=spring
- 폼 데이터(Form Data):
- HTML 폼을 통해 전송된 데이터를 매핑.
- 예: POST 요청 본문에 name=John&email=john.doe@example.com 데이터가 포함.
주요 속성
설명 | 기본값 | |
name | 요청 파라미터의 이름을 명시. | 매개변수 이름과 동일 |
required | 요청 파라미터가 필수인지 여부. | true |
defaultValue | 요청 파라미터가 없을 때 사용할 기본값. | 없음 |
@RequestParam과 다른 어노테이션 비교
어노테이션 | 설명 |
@RequestParam | 요청의 쿼리 파라미터 또는 폼 데이터를 매핑. |
@PathVariable | URL 경로의 변수 값을 매핑. |
@RequestBody | HTTP 요청 본문(body)의 데이터를 매핑 (JSON, XML 등). |
주의 사항
- 필수 속성 처리:
- 기본적으로 @RequestParam은 요청 파라미터가 없으면 에러를 발생시킵니다.
필요한 경우 required = false를 명시하거나, defaultValue를 설정하세요.
- 기본적으로 @RequestParam은 요청 파라미터가 없으면 에러를 발생시킵니다.
- 타입 변환:
- Spring은 문자열 값을 기본적으로 매핑하며, 필요한 경우 자동으로 타입 변환을 지원합니다.
단, 변환할 수 없는 타입이 지정되면 예외가 발생합니다.
- Spring은 문자열 값을 기본적으로 매핑하며, 필요한 경우 자동으로 타입 변환을 지원합니다.
@Slf4j
@Controller
public class RequestParamControllerV2 {
@ResponseBody
@GetMapping("/v1/request-param")
public String requestParamV1 (
@RequestParam("name") String userName,
@RequestParam("age") int userAge
) {
// logic
log.info("name={}", userName);
log.info("age={}", userAge);
return "success";
}
}
- @Controller + @ResponseBody
- View를 찾는 것이 아니라 ResponseBody에 응답을 작성한다(=@RestController)
- @RequestParam
- 파라미터 이름으로 바인딩한다.
- @RequestParam(”속성값”)
- 속성값이 파라미터 이름으로 매핑된다.
“속성값”과 변수명이 같으면 생략이 가능하다.
ex) @RequestParam("name") String name
// GET http://localhost:8080/v2/request-param?name=sparta&age=100
@ResponseBody
@GetMapping("/v2/request-param")
public String requestParamV2 (
@RequestParam String name,
@RequestParam int age
) {
// logic
log.info("name={}", name);
log.info("age={}", age);
return "success";
}
@RequestParam 사용법
1. 어노테이션, 속성값 모두 생략
- @RequestParam은 생략이 가능하다.
// GET http://localhost:8080/v3/request-param?name=sparta&age=100
@ResponseBody
@GetMapping("/v3/request-param")
public String requestParamV3 (
String name,
int age
) {
// logic
log.info("name={}", name);
log.info("age={}", age);
return "success";
}
- 생략하면 @RequestParam(required=false) 필수 여부 속성이 default로 설정된다.
- 단, 요청 파라미터와 이름이 완전히 같아야 한다.
- 단순 타입(int, String, Integer 등)이어야 한다.
위의 방식은 권장하지 않습니다. 명시적으로 표시되어있지 않으면 팀의 협의가 있지 않는 경우 다른 개발자들에게 혼동을 주게 됩니다. 최소 @RequestParam String name 속성 값 생략 형태를 쓰면 됩니다. |
2. required 속성 설정
- 파라미터의 필수 값을 설정한다.
- API 스펙을 규정할 때 사용한다.
@ResponseBody
@GetMapping("/v4/request-param")
public String requestParam (
@RequestParam(required = true) String name, // 필수
@RequestParam(required = false) int age // 필수가 아님
) {
// logic
log.info("name={}", name);
log.info("age={}", age);
return "success";
}
- @RequestParam을 사용하면 기본 Default값은 True이다.
- True로 설정된 파라미터 값이 요청에 존재하지 않으면 400 BadRequest(클라이언트 측 에러)
- Exception이 발생하지 않는 경우
ex) http://localhost:8080/v4/request-param?name=sparta&age=100
- Exception이 발생하는 경우
ex) http://localhost:8080/v4/request-param?age=100
ex) http://localhost:8080/v4/request-param
- required = false 설정이 되어있으면 해당 파라미터는 없어도 된다.
- 주의! http://localhost:8080/v4/request-param?name=sparta 요청한다면?
- 500 Error가 발생한다.
- int Type에는 null을 넣을 수 없다. 0이라도 들어가야 한다.
따라서 보통 null을 허용하는 Integer로 사용하거나 default 옵션을 사용한다.
@ResponseBody
@GetMapping("/v4/request-param")
public String requestParam (
@RequestParam(required = true) String name, // 필수
@RequestParam(required = false) Integer age
) {
// logic
log.info("name={}", name);
log.info("age={}", age);
return "success";
}
- 파라미터 Key값만 있고 Value가 없는 경우 http://localhost:8080/request-param?name=
- null과 빈 문자열 “”은 다르다!
- 위 형태는 빈 문자열 “” 로 인식한다, True지만 통과가 되어버린다. 주의해야 한다.
3. default 속성 적용
- 파라미터의 기본 값을 설정한다.
@ResponseBody
@GetMapping("/v5/request-param")
public String requestParam (
@RequestParam(required = true, defaultValue = "sparta") String name,
@RequestParam(required = false, defaultValue = "1") int age
) {
// logic
log.info("name={}", name);
log.info("age={}", age);
return "success"
}
- name Parameter 의 값이 없으면 기본적으로 “sparta”으로 설정한다
ex) http://localhost:8080/v5/request-param?age=100
- age Parameter의 값이 없으면 기본적으로 1 으로 설정한다.
ex) http://localhost:8080/v5/request-param?name=wonuk
ex) http://localhost:8080/v5/request-param
- 주의! defaultValue 속성을 설정하게 되면 “” 빈 문자열의 경우에도 기본 값이 설정된다.
ex) http://localhost:8080/v5/request-param?name&age
4. Map 사용
- Parameter를 Map형태로 조회가 가능하다.
@ResponseBody
@GetMapping("/v6/request-param")
public String requestParamV6(
@RequestParam Map<String, String> map
) {
// logic
log.info("name={}", map.get("name"));
log.info("age={}", map.get("age"));
return "success";
}
- Map 형태(key=value)로 조회가 가능하다
ex) http://localhost:8080/v6/request-param?name=sparta&age=100
- MultiValueMap 형태(key=[value1, value2])로 조회가 가능하다.
@ResponseBody
@GetMapping("/v6/request-param")
public String requestParamV6(
@RequestParam MultiValueMap<String, String> map
) {
// logic
log.info("name={}", map.get("name"));
log.info("age={}", map.get("age"));
return "success";
}
- ex) http://localhost:8080/v6/request-param?
- name=sparta&name=wonuk&name=tutor&age=100
💡 파라미터 Map의 Value가 1개인 경우에는 Map, 여러 개인 경우 MultiValueMap을 사용한다. 하지만 대부분의 파라미터 값은 한 개만 존재한다. |
@ModelAttribute
📌 HTTP 요청 데이터(Form 데이터, 쿼리 파라미터 등)를 객체에 바인딩하거나, 뷰에 데이터를 전달하는 데 사용됩니다.
- 요청 파라미터를 받아 필요한 Object로 바인딩 해준다. 주로 HTML 폼에서 전송된 데이터를 바인딩하고 HTTP Method POST인 경우 사용된다.
- 매개변수에 사용: 요청 데이터를 객체로 매핑.
- 메서드에 사용: 뷰에 공통 데이터를 추가.
주요 역할
1. 요청 데이터를 객체로 바인딩
- 클라이언트에서 전달된 **요청 데이터(쿼리 파라미터, 폼 데이터)**를 자동으로 객체 필드에 바인딩합니다.
- 주로 POST 요청의 폼 데이터를 처리할 때 사용됩니다.
2. 뷰(View)에 데이터 전달
- 컨트롤러 메서드에서 반환 값이 아닌, 뷰에 데이터를 추가합니다.
- 뷰에 공통적으로 전달해야 하는 데이터를 설정할 때 유용합니다.
특징 및 동작
1. 객체 생성 및 데이터 바인딩
- Spring은 @ModelAttribute를 사용하면 다음 단계를 수행합니다:
- 지정된 클래스의 객체를 생성합니다.
- 요청 데이터(쿼리 파라미터, 폼 데이터)를 객체 필드에 매핑합니다.
2. 요청 방식에 따른 동작
- GET 요청: 객체를 초기화하거나 뷰에 데이터를 전달.
- POST 요청: 폼 데이터를 객체에 바인딩.
3. 생략 가능
- @ModelAttribute는 생략 가능하며, 매개변수가 사용자 정의 객체라면 Spring이 자동으로 @ModelAttribute를 적용합니다.
주요 속성
설명 | |
value | @ModelAttribute("name") 형식으로 모델 객체의 이름을 지정. |
뷰에 데이터 전달 | 메서드에 사용하면 데이터를 뷰에 전달. |
객체 바인딩 | 매개변수에 사용하면 요청 데이터를 객체에 자동 바인딩. |
주의 사항
- 필드 이름 매칭:
- 요청 데이터의 Key와 객체 필드 이름이 동일해야 바인딩됩니다.
- Key와 필드 이름이 다르면 바인딩되지 않습니다.
- 유효성 검증:
- @Valid와 함께 사용하여 요청 데이터를 검증할 수 있습니다
- 중복 데이터 처리:
- 동일한 이름의 데이터를 여러 메서드에서 설정하면, 마지막으로 설정된 데이터가 우선합니다.
@PostMapping("/register")
public String registerUser(@Valid @ModelAttribute User user, BindingResult result) {
if (result.hasErrors()) {
return "form";
}
return "success";
}
기존 코드
@Data는 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructer를 자동으로 설정해주는 역할을 한다. 테스트 용도로만 사용하고 실무에서는 잘 사용하지 않는다.
- ex) http://localhost:8080/v1/tutor + x-www-form-urlencoded
@Data
public class Tutor {
private String name;
private int age;
}
@Controller
public class ModelAttributeController {
@ResponseBody
@PostMapping("/v1/tutor")
public String requestParamV1(
@RequestParam String name,
@RequestParam int age
) {
Tutor tutor = new Tutor();
tutor.setName(name);
tutor.setAge(age);
return "tutor name = " + name + " age = " + age;
}
}
- @RequestParam 의 Mapping을 사용하게 되면 위와 같은 객체를 생성하는 코드가 포함된다.
- @ModelAttribute 는 해당 과정을 자동화 한다.
- Postman
POST /v1/tutor
content-type: application/x-www-form-urlencoded
name=wonuk&age=100
@ModelAttribute 적용
- ex) http://localhost:8080/v2/tutor+ x-www-form-urlencoded
@ResponseBody
@PostMapping("/v2/tutor")
public String modelAttributeV2(
@ModelAttribute Tutor tutor
) {
String name = tutor.getName();
int age = tutor.getAge();
return "tutor name = " + name + " age = " + age;
}
- Postman
POST /v2/tutor
content-type: application/x-www-form-urlencoded
name=wonuk&age=100
- @ModelAttirubte 동작 순서
- 파라미터에 @ModelAttribute가 있으면 파라미터인 Tutor 객체를 생성한다.
- 요청 파라미터 이름으로 객체 필드의 Setter를 호출해서 바인딩한다.
- 파라미터 이름이 name 이면 setName(value); 메서드를 호출한다.
- 파라미터 이름과 필드 이름이 반드시 같아야 한다!
- @Data의 Setter가 없다면?
@Getter
public class Tutor {
private String name;
private int age;
}
- 객체 필드에 값이 set되지 않는다.
- 파라미터의 타입이 다른 경우
- 만약 요청 파라미터 age 에 int가 아닌 String 이 전달된다면?
POST /v2/tutor
content-type: application/x-www-form-urlencoded
name=wonuk&age=nbcamp
- BindException 발생
- 이런 경우 때문에 **Validation(검증)**이 필요하다.
@ModelAttirubte 생략
- @ModelAttribute와 지난 시간에 배운 @RequestParam은 모두 생략이 가능하다.
ex) http://localhost:8080/v3/tutor+ x-www-form-urlencoded
POST /v3/tutor
content-type: application/x-www-form-urlencoded
name=wonuk&age=100
@ResponseBody
@PostMapping("/v3/tutor")
public String modelAttributeV3(Tutor tutor) {
String name = tutor.getName();
int age = tutor.getAge();
return "tutor name = " + name + " age = " + age;
}
- Spring에서는 @RequestParam이나 @ModelAttribute가 생략되면
- String, int, Integer 와 같은 기본 타입은 @RequestParam과 Mapping한다. V4
@ResponseBody
@PostMapping("/v4/tutor")
public String requestParamV2(
String name,
int age
) {
return "tutor name = " + name + " age = " + age;
}
- 나머지 경우들(객체)은 모두 @ModelAttribute 와 Mapping한다. V3
@RequestParam vs @ModelAttribute 차이
주요 차이점
@RequestParam | @ModelAttribute | |
목적 | 특정 **단일 파라미터(쿼리 파라미터, 폼 데이터)**를 매핑. | 요청 데이터를 객체 형태로 매핑. |
대상 데이터 | 단일 Key-Value 쌍 (예: ?key=value) | 여러 Key-Value 쌍을 객체의 필드에 매핑. |
적용 대상 | 개별 매개변수. | 객체. |
데이터 출처 | 쿼리 파라미터, 폼 데이터. | 폼 데이터, 쿼리 파라미터, 경로 변수 등. |
기본값 설정 | defaultValue 속성을 통해 가능. | 객체 필드에 기본값을 설정하거나, 빈 객체 생성. |
뷰 데이터 전달 | 뷰 데이터 전달 기능 없음. | 뷰에 데이터를 전달할 수 있음 (메서드 레벨 사용). |
생략 가능 여부 | 생략 불가능 (명시적으로 사용해야 함). | 매개변수에서 생략 가능 (Spring이 자동으로 객체를 매핑). |
주요 사용 사례 | 단순 쿼리 파라미터 또는 단일 데이터 처리. | 폼 데이터나 복잡한 데이터 구조(객체) 처리. |
사용 목적에 따른 선택
@RequestParam
- 요청 데이터가 단순한 Key-Value 쌍이고, 각각 개별적으로 처리할 경우.
- 쿼리 파라미터나 단일 폼 데이터 값에 적합.
@ModelAttribute
- 요청 데이터가 객체로 표현 가능한 경우.
- 복잡한 폼 데이터(여러 필드가 있는 객체)를 처리하거나, 뷰와 데이터를 쉽게 연동할 때 유리.
요약
상황 | 선택 |
단일 쿼리 파라미터 처리. | @RequestParam |
복잡한 폼 데이터를 객체로 매핑. | @ModelAttribute |
기본값 설정이 필요한 경우. | @RequestParam |
뷰에 데이터를 전달해야 하는 경우. | @ModelAttribute |
객체 기반 데이터 처리가 필요한 경우. | @ModelAttribute |
결론
- **@RequestParam**은 단일 데이터(Key-Value) 처리에 적합하며, 간단한 요청에 사용됩니다.
- **@ModelAttribute**는 폼 데이터나 요청 데이터를 객체 형태로 처리하거나, 뷰와 연동된 데이터를 전달할 때 유용합니다.
- @RequestParam, @ModelAttribute는 GET + Query Parameter와, POST HTML Form Data를 바인딩하는 방법이다.
HTTP Message Body (요청)
📌 HTTP 요청(Request) 또는 응답(Response)에서 실제 데이터를 담는 부분입니다.
- 주로 클라이언트와 서버 간에 전송되는 JSON, XML, HTML, 바이너리 파일, 텍스트 등 다양한 콘텐츠를 포함합니다.
특징
- 이제부터 배울 내용은 HTTP Message Body에 직접적으로 Data가 전달되는 경우이다.
- Request Body의 Data를 바인딩하는 방법이다.
- REST API에서 주로 사용하는 방식이다.
- HTTP Method POST, PUT, PATCH에서 주로 사용한다.
- GET은 Request Body가 존재할 수는 있지만 권장하지 않는다.
- JSON, XML, TEXT 등을 데이터 형식으로 사용한다.
- Server에서 Request로 전달받은 Data를 처리하기 위해서 바인딩 해야 한다.
ex) JSON → Object
TEXT
📌 HTTP Request Body에 Data가 전송되는 경우 HttpMessageConverter를 통해 바인딩된다.
- 현대에는 Restful API를 주로 사용하고 있어서 대부분의 경우 JSON 형식으로 통신한다.
HttpServletRequest 예시
- request.getInputStream();
@Slf4j
@Controller
public class RequestBodyStringController {
@PostMapping("/v1/request-body-text")
public void requestBodyTextV1(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String bodyText = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
response.getWriter().write("response = " + bodyText);
}
}
- Request → Body → raw → Text
- Request Header Content-Type : text/plain
I/O 예시
- InputStream(읽기) 파라미터 지원
- HTTP Request Body Data 직접 조회
- OutputStream(쓰기) 파라미터 지원
- HTTP Response Body 직접 결과 출력
@PostMapping("/v2/request-body-text")
public void requestBodyTextV2(
InputStream inputStream,
Writer responseWriter
) throws IOException {
String body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
responseWriter.write("response = " + bodyText);
}
HttpEntity 예시
- HttpMessageConverter 사용
- HttpEntity를 사용하면 HttpMessageConverter를 사용한다.
@PostMapping("/v3/request-body-text")
public HttpEntity<String> requestBodyTextV3(HttpEntity<String> httpEntity) {
// HttpMessageConverter가 동작해서 아래 코드가 동작하게됨
String body = httpEntity.getBody();
return new HttpEntity<>("response = " + body); // 매개변수 = Body Message
}
- Spring의 HttpMessageConverter 덕분에 간편하게 Request Data에 접근할 수 있다.
- HttpEntity를 사용하면 HttpMessageConverter가 동작하여 자동으로 매핑된다.
- 요청 뿐만이 아닌 응답까지 HttpEntity 하나만으로 사용이 가능해진다.
HttpEntity
📌 HTTP 요청(Request)와 응답(Response)의 헤더(Header)와 본문(Body)을 캡슐화하는 데 사용됩니다.
- HttpEntity는 HTTP Header, Body 정보를 편리하게 조회할 수 있도록 만들어준다.
주요 특징
- 헤더(Header)와 바디(Body) 모두를 포함:
- HTTP 요청 또는 응답의 헤더와 바디를 관리.
- Immutable 객체:
- HTTP 메시지를 불변(Immutable) 상태로 다룸.
- Spring의 HTTP 클라이언트와 서버 모두에서 사용 가능:
- REST API 호출에서 요청을 보낼 때, 응답 데이터를 받을 때 활용.
HttpEntity 역할
- Http Request Body Message를 직접 조회한다
- Request 뿐만 아니라 Response도 사용할 수 있도록 만들어준다.
- Response Header 또한 사용할 수 있다.
- Request Parameter를 조회하는 기능들과는 아무 관계가 없다.
- View를 반환하지 않는다.
주요 클래스
HttpEntity는 Spring에서 두 가지 주요 클래스의 기반이 됩니다:
- RequestEntity:
- HTTP 요청을 표현.
- 요청의 헤더, URL, HTTP 메서드 등을 캡슐화.
- HTTP Request Method, URL 정보가 추가 되어있다.
- ResponseEntity:
- HTTP 응답을 표현.
- 응답의 상태 코드, 헤더, 바디를 관리.
- HTTP Response 상태 코드 설정이 가능하다.
@Controller
public class RequestBodyStringController {
@PostMapping("/v4/request-body-text")
public HttpEntity<String> requestBodyTextV4(RequestEntity<String> httpEntity) {
// HttpMessageConverter가 동작해서 아래 코드가 동작하게됨
String body = httpEntity.getBody();
// url, method 사용 가능
return new ResponseEntity<>("response = " + body, HttpStatus.CREATED); // Body Data, 상태코드
}
}
- 위 방법을 적용해도 불편하다.
- Data를 httpEntity에서 꺼내어 사용해야 한다.
Spring은 Http RequestBody Message를 읽어서 String이나 Object로 자동으로 변환해준다. 이때 HttpMessageConverter가 사용된다. |
@RequestBody, @ResponseBody
📌 Spring에서 @RequestBody, @ResponseBody 어노테이션을 사용하면 각각 Request, Response 객체의 Body에 편하게 접근하여 사용할 수 있다.
@Controller // @RestController = @Controller + @ResponseBody
public class RequestBodyStringController {
@ResponseBody
@PostMapping("/v5/request-body-text")
public String requestBodyTextV5(
@RequestBody String body,
@RequestHeader HttpHeaders headers
) {
// HttpMessageConverter가 동작해서 아래 코드가 동작하게됨
String bodyMessage = body;
return "request header = " + headers + " response body = " + bodyMessage;
}
}
- @RequestBody
- 요청 메세지 Body Data를 쉽게 조회할 수 있다.
- @RequestHeader
- 요청 헤더 정보 조회
- @ResponseBody
- 응답 메세지 바디에 값을 쉽게 담아서 전달할 수 있도록 해준다.
- View가 아닌 데이터를 반환한다.
요약
- 요청 파라미터, HTML Form Data에 접근하는 경우
- @RequestParam, @ModelAttribute 를 사용한다.
- Http Message Body에 접근하는 경우
- @RequestBody를 사용한다. (JSON, XML, TEXT)
HTTPMessageConverter
📌 HTTP 요청과 응답의 본문(Body)을 Java 객체와 직렬화 가능한 데이터(JSON, XML, 텍스트 등)로 변환하는 역할을 합니다.
- Spring MVC는 클라이언트와 서버 간 데이터를 효율적으로 교환하기 위해 HTTPMessageConverter를 사용합니다.
- MappingJackson2HttpMessageConverter는 JSON을 처리하는 대표적인 HTTPMessageConverter의 구현체이다.
HttpMessageConverter의 역할
- 데이터를 Obejct로 변환한다. 대표적으로 JSON을 변환한다.
- 요청 본문 → Java 객체 변환 (@RequestBody 사용 시):
- HTTP 요청의 JSON, XML, 텍스트 데이터를 Java 객체로 변환합니다.
- Java 객체 → 응답 본문 변환 (@ResponseBody 사용 시):
- Java 객체를 JSON, XML, 텍스트 등으로 직렬화하여 클라이언트로 전송합니다.
- @RequestBody
- 요청 데이터 + Request Header를 참고하여 Object로 변환한다.
- HTTP Request Body(JSON Data) → Converter(Jackson) → Object
- Reqeust Header → Content-Type : application/json(전달할 데이터 형식)
- 요청 데이터 + Request Header를 참고하여 Object로 변환한다.
- @ResponseBody
- 응답 데이터 + Accept Header를 참고하여 원하는 데이터 형식으로 변환한다.
- Object → Converter(Jackson) → HTTP Response Body(JSON Data)
- Request Header → Accept : application/json(허용할 데이터 형식)
- 응답 데이터 + Accept Header를 참고하여 원하는 데이터 형식으로 변환한다.
동작 원리
Spring MVC는 요청과 응답 처리 시 다음 과정을 수행합니다:
- 요청 처리:
- 클라이언트가 HTTP 요청 본문에 데이터를 포함시켜 보냅니다.
- Spring은 HttpMessageConverter를 사용하여 요청 데이터를 Java 객체로 변환.
- 응답 처리:
- 컨트롤러에서 반환한 Java 객체를 HttpMessageConverter가 JSON, XML 등으로 직렬화하여 응답 본문에 포함.
주요 HTTPMessageConverter 구현체
Spring은 다양한 데이터 형식에 따라 여러 HttpMessageConverter 구현체를 제공합니다:
구현체 | 데이터 형식 | 설명 |
MappingJackson2HttpMessageConverter | JSON | Jackson 라이브러리를 사용하여 JSON 변환 처리. |
GsonHttpMessageConverter | JSON | Gson 라이브러리를 사용하여 JSON 변환 처리. |
Jaxb2RootElementHttpMessageConverter | XML | JAXB를 사용하여 XML 변환 처리. |
StringHttpMessageConverter | Plain Text | 문자열 데이터를 처리. |
FormHttpMessageConverter | Form Data (application/x-www-form-urlencoded) | HTML 폼 데이터를 처리. |
ByteArrayHttpMessageConverter | Binary Data (byte[]) | 바이너리 데이터를 처리. |
장점
- 자동화:
- 요청과 응답 데이터를 자동으로 변환하여 개발자의 부담을 줄임.
- 유연성:
- JSON, XML, Plain Text 등 다양한 데이터 형식을 지원.
- 확장 가능성:
- 사용자 정의 HttpMessageConverter로 맞춤형 데이터 처리 가능
요약
- **HttpMessageConverter**는 HTTP 요청 및 응답의 본문 데이터를 처리하는 Spring의 핵심 컴포넌트입니다.
- 요청 데이터를 Java 객체로 변환하거나, Java 객체를 JSON, XML 등으로 변환하여 클라이언트에 전달합니다.
- Spring은 JSON 변환을 기본적으로 지원하며, 필요에 따라 사용자 정의 구현체를 추가할 수 있습니다.
'Back-End (Web) > Spring' 카테고리의 다른 글
[Spring] Server에서 Client로 Data를 전달하는 방법 (0) | 2024.12.19 |
---|---|
[Spring] HTTP Message Body & TEXT (0) | 2024.12.18 |
[Spring] Request Mapping (1) | 2024.12.16 |
[Spring] Spring Annotation (1) | 2024.12.15 |
[Spring] Spring MVC 패턴 (1) | 2024.12.14 |