본문 바로가기

Spring

스프링부트 어노테이션 / @RestController(vs @Controller) 이해하기

어플리케이션의 컨트롤러를 지정하는 어노테이션으로 @Controller 와 @RestController 가 있다.

이번 포스팅에서는 @Conrtroller 와 @RestController 의 동작이 어떻게 다른지 확인하는 방법을 통해 둘을 이해해 보려고 한다.

 

환경
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-mustache'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

 

@Controller vs @RestController 

@Controller 어노테이션은 들어온 요청에 따라 적절한 메서드 호출을 가능하게 해준다.

@RestController 도 그러하다.

예를 들어,

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MyController {

	@GetMapping("/controllerCall")
	public String controllerCall(){
		System.out.println("controllerCall 함수 호출");
		return "index";
	}
}

 

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyRestController {

	@GetMapping("/restControllerCall")
	public String restControllerCall(){
		System.out.println("restControllerCall 함수 호출");
		return "index";
	}
}

 

위와 같이 클래스가 구성되어 있을 때 http://localhost:8080/controllerCall 로 접속한다면 controllerCall() 함수가 호출되고, http://localhost:8080/restControllerCall 로 접속한다면 restControllerCall() 함수가 호출된다.

차례대로 접속해보자.

함수 호출이 잘 되는 모습이다.

하지만 노출되는 페이지는 다른 모습이었다.

 

먼저 src > main > resources > templates > index.mustache 의 모습은 다음과 같았는데,

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>
index 화면입니다.
</body>
</html>

 

http://localhost:8080/controllerCall 를 호출하면 "index 화면입니다." 라는 문구가 잘 나오는 반면

http://localhost:8080/restControllerCall 를 호출하면 "index" 라는 문구밖에 확인 할 수 없었다.

이유가 무엇일까?

 

@RestController

이유를 알기 위해서 @RestController 에 대해 알 필요가 있다.

스프링4 부터 추가된 @RestController 는 메서드의 반환값을 응답 본문으로 기록한다.

(@Controller 메서드의 반환값을 생성할 뷰의 이름으로 사용한다는 점에서 대비되는 부분이다)

 

@Controller 에서도 반환값을 응답 본문으로 기록할 때 사용하는 @ResponseBody 어노테이션이 있다.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MyController {

	@GetMapping("/controllerCall")
	@ResponseBody
	public String controllerCall(){
		System.out.println("controllerCall 함수 호출");
		return "index";
	}
}

위와 같이 구현하면 controllerCall() 함수에서 리턴값  "index" 를 응답본문으로 기록하고, restControllerCall() 이 호출되었을 때와 같은 페이지를 확인할 수 있다.

 

즉, RestController 는 @Controller 에 @ResponseBody 를 더한 것과 같은 기능이라고 볼 수 있다.

만약 api 의 기능만을 사용하는 controller 라면 @RestController 로 지정하는 것이 편할 것이다.

반응형