[Spring]Request Mapping

 

우테코에서 스프링을 공부하면서 아래 내용을 참고하여 정리한 글 입니다.

docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-requestmapping

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

 

@RequestMapping Annotion

  • controller의 method들과 요청을 매핑할 때 사용한다. 
    • 요청 URL을 어떤 메서드가 처리할지 여부를 결정
  • URL, HTTP method, request parameters, headers와 media types과 같은 다양한 속성을 가진다.
  • 공유 매핑으로 클래스 수준에서 사용하거나 엔드 포인트 매핑을 위해 메서드 수준에서 사용할 수 있다.

 

@RqusetMapping의 변형으로 바로가기 HTTP 메소드들이 있다. 컨트롤러 메서드가 기본적으로 모든 HTTP메서드와 일치하는 @RequestMapping을 사용하는 대신 특정 HTTP 메서드에 매핑되어야 하기 때문에 제공되는 사용자 지정 어노테이션이다. 공유 매핑을 표현하기 위해서 클래스 수준에서 @RequestMapping이 필요하다

 

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

 

HTTP Method 어노테이션을 사용하지 않는다면 아래와 같이 사용 할 수 있다.

@RequstMapping(value="/persons", method=RequestMethod.GET)
@RequstMapping(value="/persons", method=RequestMethod.POST)

 

 

HTTP Method 어노테이션을 사용하지 않고, method도 지정하지 않았을때

    @RequestMapping(value = "/http-method/users")
    public ResponseEntity createUser(@RequestBody User user) {
        System.out.println("user : " + user);
        Long id = 1L;
        return ResponseEntity.created(URI.create("/users/" + id)).build();
    }

 

get, post, put, delete를 다 받을 수 있다.

왜 HTTP 메소드 사용자 지정 어노테이션이 제공되는지 이해 할 수 있었다. 스프링 공식 문서에서도 이렇게 적혀 있다.

 

@RequestMapping을 사용하는 대신 특정 HTTP 메서드에 매핑되어야 하기 때문에 제공되는 사용자 지정 어노테이션이다. 

 

 

HTTP Method 어노테이션을 사용했을 때

@RestController
@RequestMapping("/persons")
class PersonController {

    @GetMapping("/{id}")
    public Person getPerson(@PathVariable Long id) {
        // ...
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void add(@RequestBody Person person) {
        // ...
    }
}

 

 

Content-Type 헤더와 Accept 헤더

  • Content-Type은 말그대로 HTTP 메시지 (요청과 응답 모두)에 담겨 보내는 데이터 형식을 알려주는 헤더.
  • 현재 전송하는 데이터가 어떤 타입인지에 대한 설명

 

  • Accept는 클라이언트에서 웹서버로 요청시 요청메시지에 담기는 헤더
  • 클라이언트가 서버에게 웹만하면 데이터 전송할 때 이러한 타입으로 가공하여 보내라고 전하는 것
  • Accept 요청을 들어주는 것은 웹서버의 마음임

 

Consumable / Producible MediaType

  • Consumable Media Type은 Content-type 요청에 기초한다.
  • 이러한 데이터를 전달하는 요청을 처리하겠다.
  • 요청에서 content-type 속성이 들어감
  • 영어 그대로 소비에 초점

 

@PostMapping(path = "/pets", consumes = "application/json")
public void addPet(@RequestBody Pet pet) {
    // ...
}

 

  • Producible Media Type은 Accept 요청에 기초한다.
  • 이러한 데이터의 응답을 원하는 요청을 처리하겠다.
  • 응답에서 content-type 속성이 들어감
  • 영어 그대로 생산에 초점

 

@GetMapping(path = "/pets/{petId}", produces = "application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId) {
    // ...
}

 

  • 하드코딩 하지 말고, 미리 정의되어 있는 ENUM값을 사용하도록 하자
@PostMapping(path = "/users", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity createUser(@RequestBody User user) {
	Long id = 1L;
    return ResponseEntity.created(URI.create("/users/" + id)).build();
}

 

  • Request에서 content-type을 지정하지 않으면
    • accept도 지정하지 않았다면 -> 415에러
    • accept를 지정했다면
      • 서버에서 accept를 처리해 준다면 -> 성공
      • 서버에서 accept를 처리해 주지 않으면 -> 415에러 발생

 

Parameters, headers

 

  • params="myParam=myValue"
    • HTTP Request URL중에 myParam이라는 파라미터가 있어야 하고 값은 myValue여야 맵핑한다.
  • params="myParam" / params="!myParam"
    • 파라미터 이름만으로 조건 부여가 가능하다. myParam이 있는 요청 / myParam이 없는 요청
@RequestMapping(params={“myParam1=myValue”, “myParam2”, ”!myParam3”})
  • myParam1이 myValue를 가지고 있고, myParam2파라미터를 가지고 있고, myParam3라는 파라미터는 없어야 함

 

 

위와 유사하게 헤더 속성또한 맵핑이 가능하다.

@GetMapping(value = "/hello", headers = HttpHeaders.FROM)

 

 

URI 매핑

 

PathVariable

 

@GetMapping("users/{id}")
public ResponseEntity<User> pathVariable(@PathVariable Long id) {
    User user = new User(id, "이름", "email");
    return ResponseEntity.ok().body(user);
}

 

Pattern

  • ?: 한글자 처리

 

  • /uri-pattern/patterns/a
  • /uri-pattern/patterns/b

 

@GetMapping("patterns/?")
public ResponseEntity<String> pattern() {
    return ResponseEntity.ok().body("pattern");
}

 

  • *: 여러글자 처리
  • **: 여러 패스, 여러 글자 처리

 

  • /uri-pattern/patterns/multi
  • /uri-pattern/patterns/all/names

 

@GetMapping("patterns/**")
public ResponseEntity<String> patternStars() {
    return ResponseEntity.ok().body("pattern-multi");
}

 

 

댓글



Designed by JB FACTORY