티스토리 뷰

@RequestMapping

요청 매핑이란?

URL 요청이 왔을 때 어떤 컨트롤러가 호출되어야 할지 매핑(mapping) 해놓은 것을 말합니다.

클래스, 메서드 위에 @RequestMapping 어노테이션을 명시함으로써 적용할 수 있습니다.

 

사용법

@ReqeustMapping("URL 경로")와 같이 작성하며, 웹 브라우저에서 서버로 URL 경로를 통해 요청이 들어오면 해당 메서드가 실행되게 됩니다.

 

즉, /test 라는 URL로 요청이 들어오면 아래와 같이 mappingTest 메서드가 실행됩니다.

@RequestMapping("/test")
public String mappingTest() {
    System.out.println("mapping test");
    return "ok";
}

 


 

HTTP 메서드 매핑 축약

@RequestMapping 어노테이션에 method 속성이 존재하는데, 해당 속성에 HTTP 메서드를 지정하지 않으면 HTTP 메서드에 무관하게 호출이 됩니다. 

즉, GET, POST, PUT, PATCH, DELETE 등 메서드에 상관없이 호출되게 됩니다.

 

@RequestMapping에 method 속성을 통해 HTTP 메서드를 지정하면, 해당 HTTP 메서드로만 호출이 가능합니다.

 

만약 지정하지 않은 HTTP 메서드를 통해 요청이 들어온다면 상태코드 405(Method Not Allowed)를 반환합니다.

 

간단하게 예를 들어보는 코드를 작성해 보겠습니다.

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String mappingTest() {
    System.out.println("mapping test");
    return "ok";
}

 

위와 같은 코드가 있을 경우, URL 요청이 GET 요청일 경우만 메서드가 실행됩니다.

 

만약 동일한 URL이지만, GET이 아닌 POST 혹은 다른 HTTP 메서드로 호출이 된다면, 사용자에게 405 에러를 보여주게 됩니다.

 

 

method 속성을 사용하면 동일한 URL이지만, 요청 메서드에 따라 각각 다른 액션을 취할 수 있는 장점이 있습니다.

하지만, 하나하나 method 속성을 지정해 주는 일은 참으로 번거롭고 반복적인 작업이지 않을 수 없습니다.

 

그래서 HTTP 메서드 중 GET, POST, PUT, PATCH, DELETE는 축약한 어노테이션을 제공한다.

종류: @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping 

 

사용법은 @RequestMapping과 동일합니다.

 

단, 주의할 점은 @RequestMapping은 Class Level과 Method Level에 붙일 수 있지만, @GetMapping, @PostMapping, @PutMapping 등의 애노테이션들은 MethodLevel에만 붙일 수 있습니다.

// GET 메서드로 요청 시 호출
@GetMapping("/test")
public String mappingGetTest() {
    System.out.println("GET 호출 test");
    return "ok";
}

// POST 메서드로 요청 시 호출
@PostMapping("/test")
public String mappingPostTest() {
    System.out.println("POST 호출 test");
    return "ok";
}

 

 

이런 게 어떻게 가능할까요?

 

스프링은 그냥 마법처럼 뚝딱 해주지 않습니다. 전부 이유가 있는 법이죠.

 

HTTP 메서드 축약 어노테이션 중 하나인 @GetMapping을 열어보면 @RequestMapping(mathod = RequestMethod.GET)과 같이 method 속성이 설정되어 있음을 확인할 수 있습니다.

 

@GetMapping뿐 아니라 다른 축약 어노테이션들도 동일하게 각자의 메서드에 맞게 설정되어 있습니다.

 


 

추가 매핑 - 속성

@RequestMapping(뿐만 아니라 축약 어노테이션 포함)은 속성을 이용하여 추가 매핑이 가능합니다.

 

 

파라미터를 통한 추가 매핑(params)

value 속성에 해당하는 URL 뒤에 query string 형식을 통하여 특정 파라미터가 있거나 없는 조건을 통해 추가 매핑할 수 있습니다. ( = 외에도!,!=, 중복 조건 등을 추가할 수 있다.)

 

아래 예제코드 같은 경우, /test-param? username=baek 요청이 들어오면 해당 메서드가 실행됩니다.

/**
 * 파라미터로 추가 매핑
 * params="mode"
 * params="!mode"
 * params="mode=debug"
 * params="mode!=debug"
 * params="["mode=debug", "data=good"}
 */
@GetMapping(value = "/test-param", params = "username=baek")
public String mappingParam() {
    System.out.println("mappingParam Test");
    return "ok";
}

 

 

헤더를 통한 추가 매핑(headers)

HTTP 요청 메시지의 header 내용을 통해 추가 매핑할 수 있는 방법이다.

 

다음은 /test-header 요청이 들어왔을 때, HTTP header에 mode라는 key의 값이 debug라면 밑의 메서드가 실행됩니다.

/**
 * 특정 헤더로 추가 매핑
 * headers="mode"
 * headers="!mode"
 * headers="mode=debug"
 * headers="mode!=debug"
 */
@GetMapping(value = "/test-header", headers = "mode=debug")
public String mappingHeader() {
    System.out.println("mappingHeader Test");
    return "ok";
}

 

 

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

HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑한다.

만약 해당 URL로 요청이 들어오지만, 미디어 타입(Content-Type)이 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)를 반환한다.

 

다음은 /test-consumes 요청에 Content-Type의 값이 "text/html"이 아닐 경우 415 상태코드를 반환한다.

@GetMapping(value = "/test-consumes", consumes = "text/html")
public String mappingConsumes() {
    System.out.println("mappingConsumes Test");
    return "ok";
}

 

 

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

HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑한다.

만약 맞지 않으면 HTTP 406 상태코드(Not Acceptable)를 반환한다.

@GetMapping(value = "/test-produce", produce = "application/json")
public String mappingProduce() {
    System.out.println("mappingProduce Test");
    return "ok";
}

 

HTTP 요청 메시지의 기본 Header들의 대해 잘 모르신다면 consumes 속성과 produce 속성에 대한 차이를 잘 모르실 수 있을 거라고 생각이 듭니다. 

 

추후에 제가 포스팅을 할 예정이오나, 아직 이해가 부족하신 분들은 검색을 통해서 Header들에 대해 기본적인 이해를 갖추시기를 권장합니다.


 

@PathVariable

@PathVariable 어노테이션을 사용하여 URL 경로에서 매칭되는 부분(변수)을 조회할 수 있습니다.

// /testGet/baek 으로 요청한 경우, username 값에 baek가 들어가게 된다.
@GetMapping("/testGet/{username}")
    public String mappingTest(@PathVariable("username") String username) {
        System.out.println("username = " + username);
        return "ok";
    }

 

만약 @PathVariable의 이름과 변수명이 같다면 아래와 같이 생략할 수 있습니다.

@GetMapping("/testGet/{username}")
    public String mappingTest(@PathVariable String username) {
        System.out.println("username = " + username);
        return "ok";
    }

 

@PathVariable을 다중으로도 사용할 수 있습니다.

// /testGet/baek/20 으로 요청한 경우, username 값에 baek, age 값에 20이 들어가게 된다.
@GetMapping("/testGet/{username}/{age}")
    public String mappingTest(@PathVariable String username, @PathVariable int age) {
        System.out.println("username = " + username);
        System.out.println("age = " + age);
        return "ok";
    }

 

 


 

참고(출처)

https://m42orion.tistory.com/117#%E2%9B%85%EF%B8%8F%20%40RequestMapping%EC%9D%B4%EB%9E%80%3F-1