728x90

Controller의 핸들러 메서드는 다양한 유형의 Argument(인수)를 지원한다.

그 중에서 REST API 애플리케이션에서 자주 사용되는 유형의 Argument를 간단히 살펴보자! 

만약, 김영한님의 스프링 강의를 들었다면 더더욱 익숙할 것이다.

Method Argument 설명
@RequestParam 쿼리 파라미터, form-data 등의 Servlet request Parameter를 바인딩 해야 할 경우 사용
@RequestHeader request header를 바인딩해서 header의 key/value에 접근 가능
@RequestBody request body를 읽어서 지정한 Java 객체로 deserialization(역직렬화) 해준다
@RequestPart 'multipart/form-data' 형식의 request 데이터를 part 별로 바인딩 가능
@PathVariable @RequestMapping 에 패턴 형식으로 정의된 URL의 변수에 바인딩 가능
@MatrixVariable URL 경로 세그먼트 부분에 key/value 쌍으로 된 데이터에 바인딩 가능
HttpEntity request header와 body에 접근할 수 있는 컨테이너 객체 사용
javax.servlet.ServletRequest, 
javax.servlet.ServletResponse
로우 레벨의 ServeletRequest와 ServletResponse의 정보가 필요할 때 사용

※ 역직렬화란? byte로 변환된 Data를 원래대로 Object나 Data로 변환하는 기술


- @RequestParam

@RequestParam은 클라이언트 쪽에서 쿼리 파라미터, form data, x-www-form-urlencoded 등의 형식으로 전달되는 요청 데이터를 바인딩해서 사용할 수 있도록 해준다.

@Controller
@RequestMapping("/coffees")
public class CoffeeController {
    // ...
    @GetMapping
    public Coffee getCoffee(@RequestParam("coffeeId") int coffeeId) {
       Coffee coffee = coffeeService.getCoffee(coffeeId);
        return coffee;
    }
    // ...
}

 

- @RequestHeader

@RequestHeader는 HTTP request header의 key/value 쌍의 데이터에 접근할 수 있도록 해준다.

@GetMapping("/coffee")
public void getCoffee(
        @RequestHeader("Content-Type") String contentType, 
        @RequestHeader("Content-Length") long contentLength) { 
    //...
}​

 

- @RequestBody

@RequestBody는 HTTP request body를 읽어서 지정한 Java 객체로 변환(deserialization) 해준다.

@PostMapping("/coffees")
public void handle(@RequestBody Coffee coffee) {
    // ...
    coffeeService.save(coffee)
}​

※ @RequestBody는 특히 리소스를 등록하는 @PostMapping에서 주로 사용된다.

 

- @RequestPart

'multipart/form-data' 형식의 request 데이터를 part 별로 바인딩할 수 있도록 해준다.

@Controller
public class CoffeeController {
    @PostMapping("/coffees")
    public String postCoffee(@RequestPart("coffee") Coffee coffee,
           @RequestPart("file") MultipartFile photoFile) {

        if (!photoFile.isEmpty()) {
            byte[] bytes = file.getBytes();
            // TODO 파일 저장
            return "success";
        }
        return "failed";
    }
}​

위 코드에 대해 설명하자면, 예를 들어 클라이언트 쪽에서 커피 사진이 포함된 multpart/form-data 타입의 커피 정보를 전송한다면,   form data를 part별로 나누어서 전달 받을 수 있다.

 

- @PathVariable

@PathVariable은 @RequestMapping 에 패턴 형식으로 정의된 URL의 변수에 바인딩할 수 있도록 해준다.

@GetMapping("/members/{member-id}/coffees/{coffee-id}")
public Pet getCoffee(@PathVariable("member-id") Long memberId,
@PathVariable("coffee-id") Long coffeeId) {
    // ...
}​

위 코드와 같이 '{variable name}'과 같은 형태의 URL 변수가 여러개 있을 경우, @PathVariable을 핸들러 메서드에 순차적으로 추가해서 URL 변수의 값을 받을 수 있다.

 

- @MatrixVariable

@MatrixVariable은 URL 경로 세그먼트 부분에 key/value 쌍으로 된 데이터에 바인딩할 수 있도록 해준다.

@MatrixVariable의 사용은 예제 코드를 보자.

// 클라이언트 요청 URL
// GET /coffees/42;q=11;r=22

@GetMapping("/coffees/{coffeeId}")
public void getCoffee(@PathVariable("coffee-id") coffeeId, 
                      @MatrixVariable int q,
                      @MatrixVariable int r) {

    // coffeeId == 42
    // q == 11
    // r == 22
}​

만약에 클라이언트 쪽 요청 URL이 '/coffees/42;q=11;r=22'와 같다면 세미콜론(;) 뒤에 오는 q, r을 변수로 보고 각 변수의 값을 위와 같이 핸들러 메서드에서 전달 받을 수 있다.

 

- HttpEntity

클라이언트 요청 body와 header 정보를 HttpEntity 객체를 통해 한번에 전달 받을 수 있다.

물론 HttpServletRequest 객체를 통해서도 요청 body와 header에 접근할 수 있지만 HttpEntity 객체를 통해 조금 더 간단하게 두 정보에 접근할 수 있다.

@RestController
@RequestMapping("/v1/coffees")
public class HttpEntityExample {
    @PostMapping
    public Coffee postCoffee(HttpEntity<Coffee> entity) {
        Coffee coffee = entity.getBody();
        HttpHeaders headers = entity.getHeaders();
        
        // coffee 정보 저장
        return coffee;
    }
}​
728x90

+ Recent posts