숑숑이의 개발일기

요청 매핑

@Controller는 반환 값이 String이라면 View 이름으로 인식된다. 그래서 해당 이름의 뷰를 찾고 뷰를 랜더링 한다. 그러나 @RestController는 반환 값으로 뷰를 찾는 것이 아닌, HTTP 메시지 바디에 바로 입력한다.

 

@RequestMapping에서 속성을 배열로 하여 다중 설정을 할 수도 있다.

    @RequestMapping(value = {"/hello-basic", "/hello-go"}, method = RequestMethod.GET)
    public String helloBasic() {
        log.info("helloBasic");
        return "ok";
    }

@RequestMapping을 사용시에는 method 속성을 지정하지 않으면 HTTP 메서드와 무관하게 호출되므로, GET, HEAD, POST, PUT, PATCH, DELETE 메서드로 호출 시 모두 호출된다.

 

고로 HTTP 특정 메서드 요청만 허용하는 축약형 어노테이션을 활용하는 것을 추천한다.

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

@GetMapping 뿐만아니라, Post, Put, Delete, Patch모두 지원한다.

 

최근 HTTP API는 아래와 같이 리소스 경로에 식별자를 넣는 스타일을 선호한다. 이를 경로변수라 한다.

@GetMapping("/mapping/{userId}")
	public String mappingPath(@PathVariable("userId") String data) {
        log.info("mappingPath userId={}", data);
        return "ok";
}

참고로 매개변수의 변수명과, @PathVariable의 이름이 동일하다면, 아래와 같이 생략하여 사용할 수 있다.

 

    @GetMapping("/mapping/{userId}")
    public String mappingPath(@PathVariable String userId) {
        log.info("mappingPath userId={}", userId);
        return "ok";
    }

 

물론, 아래와 같이 다중사용도 가능하다.

@GetMapping("/mapping/users/{userId}/orders/{orderId}")
    public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
        log.info("mappingPath userId={}, orderId={}", userId, orderId);
        return "ok";
    }

 

특정 파라미터가 있거나 없는 조건을 추가할 수 있는데, 잘 사용하지는 않는다.

아래의 코드의 경우에는, /mapping-param?mode=debug 형식의 url이 아니라면 400에러가 발생한다.

/**
     * 파라미터로 추가 매핑
     * params="mode",
     * params="!mode"
     * params="mode=debug"
     * params="mode!=debug" (! = )
     * params = {"mode=debug","data=good"}
     */
    @GetMapping(value = "/mapping-param", params = "mode=debug")
    public String mappingParam() {
        log.info("mappingParam");
        return "ok";
    }

 

 

파라미터 매핑과 비슷하지만, HTTP 헤더를 사용하는 특정 헤더 조건 매핑도 가능하다.

    /**
     * 파라미터로 추가 매핑
     * headers="mode",
     * headers="!mode"
     * headers="mode=debug"
     * headers="mode!=debug" (! = )
     */
    @GetMapping(value = "/mapping-header", headers = "mode=debug")
    public String mappingHeader() {
        log.info("mappingHeader");
        return "ok";
    }

 

미디어 타입 조건 매핑

    /**
     * Content-Type 헤더 기반 추가 매핑 Media Type
     * consumes="application/json"
     * consumes="!application/json"
     * consumes="application/*"
     * consumes="*\/*"
     * MediaType.APPLICATION_JSON_VALUE
     */
    @PostMapping(value = "/mapping-consume", consumes = "application/json")
    public String mappingConsumes() {
        log.info("mappingConsumes");
        return "ok";
    }

    /**
     * Accept 헤더 기반 Media Type
     * produces = "text/html"
     * produces = "!text/html"
     * produces = "text/*"
     * produces = "*\/*"
     */
    @PostMapping(value = "/mapping-produce", produces = "text/html")
    public String mappingProduces() {
        log.info("mappingProduces");
        return "ok";
    }
  • consumes : 서버가 받을 수 있는 콘텐츠 타입. 맞지않으면 415 상태코드를 반환
  • produces : 클라이언트가 받을 수 있는 콘텐츠 타입. 맞지 않으면 406 상태코드를 반환

 

API 예시

회원 관리를 HTTP API로 만든다 생각하고 매핑을 어떻게 하는지 알아보도록 한다.

 

예시로 아래와같이 API를 정의했다 가정한다.

  • 회원 목록 조회 : GET, /users
  • 회원 등록 : POST, /users
  • 회원 조회 : GET, /users/{userId}
  • 회원 수정 : PATCH, /users/{userId}
  • 회원 삭제 : DELETE, /users/{userId}
package hello.springmvc.basic.requestmapping;

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

@RestController
@RequestMapping("/mapping/users")
public class MappingClassController {
    @GetMapping
    public String users() {
        return "get users";
    }

    @PostMapping
    public String addUser() {
        return "post user";
    }

    @GetMapping("/{userId}")
    public String findUser(@PathVariable String userId) {
        return "get user=" + userId;
    }

    @PatchMapping("/{userId}")
    public String updateUser(@PathVariable String userId) {
        return "update user=" + userId;
    }

    @DeleteMapping("/{userId}")
    public String deleteUser(@PathVariable String userId) {
        return "delete user=" + userId;
    }

}

 

위 글은 김영한 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술의 일부 내용을 정리한 것입니다.

 

profile

숑숑이의 개발일기

@숑숑-

풀스택 개발자 준비중입니다