본문 바로가기
Spring MVC

[MVC] 스프링 MVC - 기본 기능(2)

by 개발 Blog 2025. 2. 24.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

 

요청 매핑

스프링 MVC에서는 @RequestMapping 및 축약된 애노테이션(@GetMapping, @PostMapping 등)을 사용하여 HTTP 요청을 특정 컨트롤러 메서드와 매핑할 수 있다.

 

기본 요청 매핑

@RestController
public class MappingController {
    private Logger log = LoggerFactory.getLogger(getClass());

    /**
     * 기본 요청
     * /hello-basic, /hello-basic/ 허용
     * HTTP 메서드 모두 허용 (GET, HEAD, POST, PUT, PATCH, DELETE)
     */
    @RequestMapping("/hello-basic")
    public String helloBasic() {
        log.info("helloBasic");
        return "ok";
    }
}
  • @RequestMapping("/hello-basic")
    • /hello-basic URL 요청이 오면 해당 메서드를 실행하도록 매핑한다.
    • HTTP 메서드(GET, POST 등) 제한 없이 모든 요청을 허용한다.
  • @RestController
    • 반환 값을 뷰가 아닌 HTTP 응답 바디로 직접 전송한다. (@ResponseBody 포함)

스프링 부트 3.0 이후 변경 사항

  • 기존(3.0 이전): /hello-basic와 /hello-basic/을 같은 요청으로 매핑
  • 변경(3.0 이후): /hello-basic와 /hello-basic/은 서로 다른 URL로 취급됨

HTTP 메서드 매핑

@RequestMapping의 method 속성을 사용하여 특정 HTTP 메서드 요청만 허용할 수 있다.

@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
    log.info("mappingGetV1");
    return "ok";
}
  • 위 메서드는 GET 요청만 허용한다.
  • 다른 HTTP 메서드(예: POST)로 요청하면 405 Method Not Allowed 응답이 반환된다.

HTTP 메서드 매핑 - 축약 애노테이션

@GetMapping("/mapping-get-v2")
public String mappingGetV2() {
    log.info("mapping-get-v2");
    return "ok";
}

축약된 HTTP 메서드 매핑 애노테이션

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

@GetMapping("/mapping-get-v2")
→ 내부적으로 @RequestMapping(value = "/mapping-get-v2", method = RequestMethod.GET)과 동일하다.

 

경로 변수(PathVariable) 사용

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
    log.info("mappingPath userId={}", data);
    return "ok";
}
  • 요청 예시: http://localhost:8080/mapping/userA
  • PathVariable을 사용하면 URL 경로의 일부를 변수로 받을 수 있다.
  • @PathVariable("userId") String data → @PathVariable String userId로 생략 가능

다중 PathVariable 사용

@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
    log.info("mappingPath userId={}, orderId={}", userId, orderId);
    return "ok";
}
  • 요청 예시: http://localhost:8080/mapping/users/userA/orders/100
  • userId와 orderId를 경로 변수로 받아 사용할 수 있다.

특정 파라미터 조건 매핑

@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
    log.info("mappingParam");
    return "ok";
}
  • 요청 예시: http://localhost:8080/mapping-param?mode=debug
  • 특정 쿼리 파라미터가 있는 경우에만 매핑된다.
  • params="!mode": mode 파라미터가 없는 경우 매핑

특정 헤더 조건 매핑

@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
    log.info("mappingHeader");
    return "ok";
}
  • 요청 시 특정 HTTP 헤더(mode=debug)가 포함되어 있어야 매핑된다.
  • headers="!mode": mode 헤더가 없는 경우 매핑

✔ 테스트 방법:
Postman 또는 HTTP 클라이언트에서 헤더 추가 후 요청

 

미디어 타입(Content-Type) 조건 매핑

@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
    log.info("mappingConsumes");
    return "ok";
}
  • Content-Type이 application/json인 경우에만 요청을 처리한다.

요청 예시

{
    "username": "spring"
}
  • consumes="text/plain" → text/plain 타입의 요청만 처리 가능

✔ MediaType.APPLICATION_JSON_VALUE와 같이 상수 사용 가능

 

미디어 타입(Accept) 조건 매핑

@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
    log.info("mappingProduces");
    return "ok";
}
  • 클라이언트가 Accept: text/html을 포함한 요청을 보낼 경우에만 응답을 처리한다.

요청 예시 (Accept 헤더 설정):

Accept: text/html

✔ produces = "application/json" → JSON 응답만 허용 가능
✔ produces = MediaType.TEXT_PLAIN_VALUE 와 같은 상수 사용 가능

정리

요청 매핑 방식 정리

매핑 방식 애노테이션 설명
기본 요청 매핑 @RequestMapping("/path") 모든 HTTP 메서드 허용
GET 요청 매핑 @GetMapping("/path") GET 요청만 허용
POST 요청 매핑 @PostMapping("/path") POST 요청만 허용
경로 변수 사용 @PathVariable URL 경로에 변수를 포함
특정 파라미터 매핑 params="mode=debug" 특정 쿼리 파라미터 존재 시 매핑
특정 헤더 매핑 headers="mode=debug" 특정 HTTP 헤더가 있을 때 매핑
Content-Type 매핑 consumes="application/json" 요청의 Content-Type이 특정 값일 때 매핑
Accept 매핑 produces="text/html" 응답이 특정 미디어 타입일 때 매핑

 

추천하는 요청 매핑 방식

  • HTTP 메서드는 축약된 애노테이션 (@GetMapping, @PostMapping)을 사용
  • 경로 변수 사용 시 @PathVariable을 활용
  • 특정 조건이 필요한 경우 params, headers, consumes, produces 옵션 사용
  • Postman으로 테스트하면서 정확한 동작 확인

요청 매핑 - API 예시

회원 관리를 위한 HTTP API를 만들 때, 요청을 어떻게 매핑하는지 알아보자. 실제 데이터를 처리하는 부분은 생략하고, URL 매핑만 다루도록 한다.

 

회원 관리 API

기능 HTTP 메서드 URL
회원 목록 조회 GET /users
회원 등록 POST /users
회원 조회 GET /users/{userId}
회원 수정 PATCH /users/{userId}
회원 삭제 DELETE /users/{userId}

 

MappingClassController

아래는 @RequestMapping을 활용하여 회원 관리 API의 URL 매핑을 설정한 예제이다.

package hello.springmvc.basic.requestmapping;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/mapping/users")
public class MappingClassController {

    /**
     * GET /mapping/users
     */
    @GetMapping
    public String users() {
        return "get users";
    }

    /**
     * POST /mapping/users
     */
    @PostMapping
    public String addUser() {
        return "post user";
    }

    /**
     * GET /mapping/users/{userId}
     */
    @GetMapping("/{userId}")
    public String findUser(@PathVariable String userId) {
        return "get userId=" + userId;
    }

    /**
     * PATCH /mapping/users/{userId}
     */
    @PatchMapping("/{userId}")
    public String updateUser(@PathVariable String userId) {
        return "update userId=" + userId;
    }

    /**
     * DELETE /mapping/users/{userId}
     */
    @DeleteMapping("/{userId}")
    public String deleteUser(@PathVariable String userId) {
        return "delete userId=" + userId;
    }
}

@RequestMapping("/mapping/users") 활용

  • 클래스 레벨에 @RequestMapping("/mapping/users")를 설정하면, 이 경로가 기본적으로 모든 메서드 앞에 적용된다.
  • 각 메서드는 @GetMapping, @PostMapping, @PatchMapping, @DeleteMapping 등을 활용하여 세부적인 경로와 HTTP 메서드를 매핑한다.
  • @PathVariable을 사용하여 URL 경로 변수({userId})를 메서드 매개변수로 받을 수 있다.

Postman을 이용한 테스트

아래 URL을 이용하여 Postman 또는 URL로 요청을 보내면서 동작을 확인할 수 있다.

기능 요청 방법 URL
회원 목록 조회 GET /mapping/users
회원 등록 POST /mapping/users
회원 조회 GET /mapping/users/id1
회원 수정 PATCH /mapping/users/id1
회원 삭제 DELETE /mapping/users/id1

 

HTTP 요청 - 기본, 헤더 조회

스프링 컨트롤러는 다양한 방식으로 HTTP 요청 정보를 조회할 수 있다. 이번에는 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 javax.servlet.http.HttpServletRequest;
import javax.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";
    }
}

주요 기능 설명

1. HttpServletRequest, HttpServletResponse

  • HttpServletRequest: HTTP 요청 정보를 직접 조회할 수 있다.
  • HttpServletResponse: HTTP 응답을 직접 다룰 수 있다.

2. HttpMethod

  • HttpMethod를 사용하면 요청이 GET, POST, PUT, DELETE 등 어떤 HTTP 메서드로 왔는지 확인할 수 있다.

3. Locale

  • 클라이언트의 지역(Locale) 정보를 조회할 수 있다. (예: ko_KR, en_US)

4. @RequestHeader MultiValueMap<String, String> headerMap

  • 모든 HTTP 헤더를 MultiValueMap 형식으로 조회한다.
  • MultiValueMap은 하나의 키에 여러 개의 값을 저장할 수 있는 구조이다.
  • 예제:
MultiValueMap<String, String> map = new LinkedMultiValueMap();
map.add("keyA", "value1");
map.add("keyA", "value2");
List<String> values = map.get("keyA"); // [value1, value2]

 

@Slf4j 로깅 기능

@Slf4j 애노테이션을 사용하면 다음과 같은 로깅 코드가 자동으로 생성된다.

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

개발자는 log.info(), log.debug() 등의 메서드를 사용하여 편리하게 로그를 출력할 수 있다.

 

참고 자료