HTTP는 메서드와 URI를 이용해 서버에 HTTP요청을 보낼 수있다. 서버는 이 요청을 받은 후 어떻게 처리 해야 할까?
http GET 메서드를 이용해 test라는 리소스를 요청한다는 뜻이다. 따라서 서버는 자신의 주소를 제외한 /{리소스} 부분을 이해하고, 또 이 요청이 어떤 HTTP 메서드를 이용했는지 알아야 한다. 그 후 해당 리소스의 HTTP 메서드에 연결된 메서드를 실행해야 한다.
스프링 부트 스타터 웹의 어노테이션을 이용하면 이 연결을 쉽게 할 수 있다.
implementation 'org.springframework.boot:spring-boot-starter-web'
@RestController
@RequestMapping("test") //리소스
public class TestController {
@GetMapping
public String testController() {
return "Hello world!";
}
}
@RestController를 이용하면 http 관련된 코드 및 요청/응답 매핑을 스프링이 알아서 해준다.
@GetMapping 어노테이션을 이용해 이 메서드의 리소스와 HTTP 메서드를 지정한다. 클라이언트가 이 리소스에 대해 Get 메서드로 요청하면 @GetMapping에 연결된 컨트롤러가 실행된다.
만약 /test/{id}처럼 PathVariable 이나 /test?id=123 처럼 요청 매개변수를 받아야 한다면 어떻게 해야할까?
@PathVariable을 이용하면 /{id}와 같이 URI의 경로로 넘어오는 값을 변수로 받아 올수 있다.
@GetMapping("/{id}")
public String testControllerWithPathVariable(@PathVariable(required = false) int id)
{
return "Hello World! ID " + id;
}
//(requierd = false)은 이 매개변수가 꼭 필요한건 아니라는 뜻이다.
@RequestParam을 이용하면 ?id={id}와 같이 요청 매개변수로 넘어오는 값을 변수로 받아올 수 있다.
// /test 경로는 이미 존재하므로 /test/testRequestParam으로 지정했다.
@GetMapping("/testRequestParam")
public String testControllerRequestParam(@RequestParam(required = false) int id) {
return "Hello World! ID " + id;
}
RequestBody는 보통 반환하고자 하는 리소스가 복잡할 때 사용한다. 기본 자료형이 아닌 오브젝트처럼 복잡한 자료형을 통째로 요청에 보내고 싶은 경우가 이에 해당한다.
package com.example.demo.dto;
import lombok.Data;
@Data
public class TestRequestBodyDTO {
private int id;
private String message;
}
//TestRequestBodyDTO 생성
// /test 경로는 이미 존재하므로 /test/testRequestBody로 지정했다.
@GetMapping("/testRequestBody")
public String testControllerRequestBody(@RequestBody TestRequestBodyDTO testRequestBodyDTO) {
return "Hello world! ID " + testRequestBodyDTO.getId()
+ " Message : " + testRequestBodyDTO.getMessage();
}
//TestRequestBodyDTO를 요청 바디로 받는 testControllerRequestBody()메서드 생성
@RequestBody TestRequestBodyDTO testRequestBodyDTO는 RequestBody로 날아오는 JSON을 TestRequestBodyDTO 오브젝트로 변환해 가져오라는 뜻이다.
@RestController를 이루는 두개의 어노테이션중 하나는 @Controller고 다른 하나는@ReponseBody이다. @Controller를 더 들여다 보면 @Component로 스프링이 이 클래스의 오브젝트를 알아서 생성하고 다른 오브젝트들과의 의존성을 연결한다는 뜻이다.
@ResponseBody는 이 클래스의 메서드가 리턴하는 것은 웹 서비스의 ResponseBody라는 뜻이다. 메서드가 리턴할 때 스프링은 리턴된 오브젝트를 JSON의 형태로 바꾸고 HttpResponse에 담아 반환한다는 뜻이다.
@GetMapping("/testResponseBody")
public ResponseDTO<String> testControllerResponseBody() {
List<String> list = new ArrayList<>();
list.add("Hello World! I`m ResponseDTO");
ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
return response;
}
ResponseEntity는 HTTP 응답의 바디뿐만 아니라 여러 다른 매개변수들(status,header 등)을 조작하고 싶을 때 사용한다.
@GetMapping("/testResponseEntity")
public ResponseEntity<?> testControllerResponseEntity() {
List<String> list = new ArrayList<>();
list.add("Hello World! I`m ResponseEntity. And you got 200!");
ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
//http status를 200으로 설정.
return ResponseEntity.ok().body(response);
}
ResponseDTO를 리턴하는 것과 비교했을 때 리턴된 Body는 아무 차이가 없다. 단지 헤더와 HTTP status를 조작할 수 있다는 점이 다르다.