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의 정보가 필요할 때 사용할 수 있습니다.

 

@RequestParam

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
@RequestMapping("/coffees")
public class CoffeeController {
 
    // ...
 
    @GetMapping
    public Coffee getCoffee(@RequestParam("coffeeId"int coffeeId) {
       Coffee coffee = coffeeService.getCoffee(coffeeId);
        return coffee;
    }
 
    // ...
 
}
[코드 1-1]
cs

 

@RequestHeader

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

1
2
3
4
5
6
@GetMapping("/coffee")
public void getCoffee(
        @RequestHeader("Content-Type"String contentType, 
        @RequestHeader("Content-Length"long contentLength) { 
    //...
}
[코드 1-2]
cs

 

@RequestBody

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

1
2
3
4
5
@PostMapping("/coffees")
public void handle(@RequestBody Coffee coffee) {
    // ...
    coffeeService.save(coffee)
}
[코드 1-3]
cs

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

 

@RequestPart

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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";
    }
}
[코드 1-4]
cs

예를 들어, 클라이언트 쪽에서 커피 사진이 포함된 multpart/form-data 타입의 커피 정보를 전송한다면,  [코드 1-4]와 같이  form data를 part별로 나누어서 전달 받을 수 있습니다.

 

@PathVariable

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

1
2
3
4
@GetMapping("/members/{member-id}/coffees/{coffee-id}")
public Pet getCoffee(@PathVariable("member-id") Long memberId,
@PathVariable("coffee-id") Long coffeeId) {
    // ...
}
[코드 1-5]
cs

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

 

@MatrixVariable

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

@MatrixVariable의 사용은 예제 코드를 보는게 가장 이해가 빠릅니다.

1
2
3
4
5
6
7
8
9
10
11
12
// 클라이언트 요청 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
}
[코드 1-6]
cs

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

 

HttpEntity

클라이언트 요청 body와 header 정보를 HttpEntity 객체를 통해 한번에 전달 받을 수 있습니다. 물론 HttpServletRequest 객체를 통해서도 요청 body와 header에 접근할 수 있지만 HttpEntity 객체를 통해 조금 더 간단하게 두 정보에 접근할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
@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;
    }
}
[코드 1-7]
cs

 

+ Recent posts

출처: http://large.tistory.com/23 [Large]