[Spring] HTTP 요청 및 응답

윤짱·2026년 1월 14일

Spring

목록 보기
13/18
post-thumbnail

강의 정보 : 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (김영한)


HTTP 요청 - 기본, 헤더 조회

RequestHeaderController

package hello.springmvc.basic.request;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Locale;

@Slf4j
@RestController
public class RequestHeaderController {

    @RequestMapping("/headers")
    public String headers(HttpServletRequest request,
                          HttpServletResponse response,
                          HttpMethod httpMethod,
                          Locale locale,
                          @RequestHeader MultiValueMap<String, String> headerMap,
                          @RequestHeader("host") String host,
                          @CookieValue(value = "myCookie", required = false) String cookie
                          ) {

        log.info("request={}", request);
        log.info("response={}", response);
        log.info("httpMethod={}", httpMethod);
        log.info("locale={}", locale);
        log.info("headerMap={}", headerMap);
        log.info("header host={}", host);
        log.info("myCookie={}", cookie);
        return "ok";
    }
}

@Slf4j
다음 코드를 자동으로 생성해서 로그를 선언해준다. 개발자는 편리하게 log 라고 사용하면 된다.

private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger(RequestHeaderController.class);

HTTP 요청 파라미터

클라이언트에서 서버로 요청 데이터를 전달할 때는 주로 다음 3가지 방법을 사용한다.

GET - 쿼리 파라미터

  • /url?username=hello&age=20
  • 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
  • 예) 검색, 필터, 페이징등에서 많이 사용하는 방식

POST - HTML Form

  • content-type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파리미터 형식으로 전달 username=hello&age=20
  • 예) 회원 가입, 상품 주문, HTML Form 사용

HTTP message body에 데이터를 직접 담아서 요청

  • HTTP API에서 주로 사용, JSON, XML, TEXT
  • 데이터 형식은 주로 JSON 사용
  • POST, PUT, PATCH

쿼리 파라미터, HTML Form

package hello.springmvc.basic.request;

import hello.springmvc.basic.HelloData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Slf4j
@Controller
public class RequestParamController {

  /**
  * 반환 타입이 없으면서 이렇게 응답에 값을 직접 집어넣으면, view 조회X
  */
  @RequestMapping("/request-param-v1")
  public void requestParamV1(HttpServletRequest request, HttpServletResponse
  response) throws IOException {
		String username = request.getParameter("username");
		int age = Integer.parseInt(request.getParameter("age"));
		log.info("username={}, age={}", username, age);

		response.getWriter().write("ok");
	}
}

request.getParameter()

여기서는 단순히 HttpServletRequest가 제공하는 방식으로 요청 파라미터를 조회했다.

이제 스프링에서 요청 파라미터를 조회하는 방식에 대해 설명하겠다.

@RequestParam

— 파라미터 바인딩, @ResponseBody, 생략 가능 여부를 중심으로

@RequestParam에 대한 설명은 “파라미터 이름으로 바인딩한다”, “뷰 조회를 무시한다”, “단순 타입이면 생략 가능하다” 등이 있지만, 나에게는 추상적인 느낌이 있어서 다시 정리해 보고자 한다.

이 글에서는 아래와 순서로 정리한다.

개념 → 동작 흐름 → @ResponseBody 의미 → 생략 가능 여부

개념

@RequestParamHTTP 요청에 포함된 파라미터(name=value 형태)를 기준으로 값을 추출하여 컨트롤러 메서드 파라미터에 값을 바인딩하는 어노테이션이다.

동작 흐름

바인딩의 의미를 잘 이해하기 위해 HTTP 요청 흐름을 단계별로 설명해 보고자 한다.

다음과 같은 코드가 있을 때,

@GetMapping("/meals")
public ResponseEntity<?> getMeals(@RequestParam String day) {
	...
}
  1. 클라이언트는 서버로 요청을 보낼 때 "name=value"의 형태로 요청을 보낸다.
  2. @RequestParam요청 파라미터 중 이름이 day인 값을 찾아 메서드 파라미터 day에 값을 자동 주입하고 이를 파라미터 이름으로 바인딩한다고 한다. 따라서 파라미터의 이름이 기준이 된다.

@ResponseBody

@ResponseBody의 기능을 한 문장으로 설명하면 컨트롤러의 반환값을 View 이름으로 해석하지 않고 HTTP Response Body에 그대로 작성하는 것이다. 이 역시 코드와 함께 보면 이해가 쉽다.

아래와 같은 코드가 있을 때,

@RequestMapping("/hello")
public String hello() {
    return "hello";
}

Spring에서는 다음과 같이 작동한다.

return "hello"

ViewResolver에게 "hello"라는 이름의 View를 찾아라

hello.html / hello.jsp 같은 템플릿 탐색

HTML 렌더링 후 응답

이를 뷰 조회라고 한다.

그러나 이 코드에 @ResponseBody가 붙으면 Spring은

@ResponseBody가 존재하므로 이 메서드의 반환값은 view 이름이 아니기 때문에 이 값을 그대로 HTTP 응답 본문에 작성한다. 즉, 리턴 값이 바디의 내용이 되도록 만드는 것이다.

생략 가능

컨트롤러 메서드 파라미터가 String, int, Integer와 같은 단순 타입의 경우 다른 어노테이션이 붙어 있지 않으면 @RequestParam으로 간주할 수 있다.

그러나 실무의 관점에서는
1. 이 값이 어디서 오는지 코드만 보고 확인하는 것이 어렵고,
2. 필수 여부 및 기본값이 불명확해지거나,
3. 리팩토링 시 실수 위험도가 증가하고,
4. 명시성 관점에서는 좋지 않다.

따라서 단순 타입의 경우 @RequestParam의 생략이 가능하지만 가독성과 명확성을 위해 명시적으로 사용하는 것이 바람직하다.

@ModelAttribute

요청 파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣는 과정을 완전히 자동화하는 기능

스프링MVC는 @ModelAttribute 가 있으면 다음을 실행한다.

  • 요청 파라미터를 바인딩 받을 객체HelloData(예시)를 생성한다.
  • 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾는다. 그리고 해당 프로퍼티의 setter를 호출해서 파라미터의 값을 입력(바인딩) 한다.
  • 예) 파라미터 이름이 username 이면 setUsername() 메서드를 찾아서 호출하면서 값을 입력한다.

HTTP 응답

HTTP API, 메시지 바디에 직접 입력

@RestController
@Controller 대신에 @RestController 애노테이션을 사용하면, 해당 컨트롤러에 모두 @ResponseBody
적용되는 효과가 있다. 따라서 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 데이터를 입력한다. 이름
그대로 Rest API(HTTP API)를 만들 때 사용하는 컨트롤러이다.
참고로 @ResponseBody 는 클래스 레벨에 두면 전체 메서드에 적용되는데, @RestController 에노테이션 안에
@ResponseBody 가 적용되어 있다.

HTTP 메시지 컨버터

profile
바르게 살자...

0개의 댓글