안녕하세요.
#yeoneeblog 여니입니다:)
@Controller와 @RestController 차이점
Spring에서 클래스에 컨트롤러를 지정해주기 위한 어노테이션은 @Controller와 @RestController가 있습니다.
이번에는 이 2가지 어노테이션의 차이점에 대해 정리할 것입니다.
이 2가지의 주요 차이점은 HTTP ResponseBody가 생성되는 방식이고, @Controller + @ResponseBody 조합이 @RestController이라 말할 수 있습니다.
1. @Controller이란?
전통적인 Spring MVC의 컨트롤러 어노테이션인 @Controller는 주로 View(화면)를 반환하기 위해 사용합니다.
@Controller
public class TestController {
// @RequestMapping(value = "api/board/update", method = {RequestMethod.POST})
@PostMapping("api/board/update")
public String update() {
return "update";
}
}
아래와 같은 과정을 통해서 Spring MVC Container는 Client 요청으로부터 View를 반환합니다.
[과정]
1.Client는 URL형식으로 요청을 보낸다.
2.DispatcherServlet이 요청을 위임할 Handler Mapping을 찾는다.
3.Handler Mapping을 통해 요청을 Controller로 위임한다.
4.Controller는 요청을 처리한 후 View Name을 Handler Adapter한테 반환한다.
5.Handler Adapter는 이걸 DispatcherServlet한테 반환한다.
6.DispatcherServlet는 View Resolver를 통해 View Name에 해당하는 View를 찾아서 Client한테 반환한다.
위의 과정을 거치면서 View를 찾아서 렌더링 하는 과정을 거치게 됩니다.
하지만 Spring MVC의 컨트롤러를 사용할 때 Data를 반환해야 하는 경우도 있습니다.
컨트롤러에서 Data를 반환하기 위해 @ResponseBody 어노테이션을 활용해서 JSON 형태의 데이터를 반환할 수 있습니다.
[과정]
1.Client는 URL형식으로 요청을 보낸다.
2.DispatcherServlet이 요청을 위임할 Handler Mapping을 찾는다.
3.Handler Mapping을 통해 요청을 Controller로 위임한다.
4.Controller는 요청을 처리한 후 객체를 반환한다.
5.반환되는 객체는 JSON으로 직렬화(Serialize)돼서 Client에게 반환된다.
컨트롤러를 통해 객체(데이터)를 반환할 대 일반적으로 ResponseEntity로 감싸서 반환합니다.
그리고 객체를 반환하기 위해서는 View를 반환할 때 사용된 View Resolver 대신에 HttpMessageConverter가 동작합니다.
HttpMessageConverter에는 여러 Converter가 등록되어 있고, 반환하는 데이터에 따라 사용되는 Converter가 달라집니다.
단순 문자열인 경우 StringHttpMessageConverter가 사용되고, 객체인 경우에는 MappingJackson2HttpMessageConverter가 사용되고, 데이터의 종류에 따라 서로 다른 MessageConverter가 작동하게 됩니다.
Spring은 Client의 HTTP Accept Header와 서버의 컨트롤러 반환 타입 정보 2개를 조합해서 적합한 HttpMessageConverter를 선택해서 처리합니다. Message Converter가 동작하는 시점은 HandlerAdapter와 Controller가 요청을 주고받는 시점입니다.
상단 그림을 보면 4번에서 Message를 객체로 변환, 6번에서는 객체를 Message로 변환하는데 Message Converter가 사용됩니다.
@Controller
@RequiredArgsConstructor
public class TestController {
private final MemberService memberService;
@GetMapping("api/board/member")
public @ResponseBody ResponseEntity<Member> findMember(@RequestParam("id") String id) {
return ResponseEntity.ok(memberService.findMember(member));
}
}
상단 코드에서 findMember()는 Member이라는 이름을 가진 객체를 ResponseEntity로 감싸서 반환하고, Member를 JSON으로 반환하기 위해 @ResponseBody 어노테이션을 붙여주었습니다.
이 2가지를 한 곳에 작성하는 것보다는 데이터를 반환하는 Controller와 View를 반환하는 Controller를 분리해서 작성하는 것이 더욱 좋은 방법입니다.
2. @RestController이란?
@RestController 어노테이션은 Restful Web Service에서 사용되는 컨트롤러 어노테이션입니다.
@Controller + @ResponseBody가 합쳐진 형태로 JSON 형태의 객체 데이터를 반환합니다.
@RestController
@RequiredArgsConstructor
public class TestController {
private final MemberService memberService;
@GetMapping("api/board/member")
public Member findMember(@RequestParam("id") String id) {
return memberService.findMember(member);
}
@GetMapping("api/board/member")
public ResponseEntity<Member> findMemberResponseEntity(@RequestParam("id") String id) {
return ResponseEntity.ok(memberService.findMember(member));
}
}
findMember()는 Member 객체 그대로를 반환하고 있습니다.
이러한 경우에 문제는 Client가 예상하는 HttpStatus를 설정할 수 없기에 객체 생황에 맞는 ResponseEntity로 감싸서 반환해줘야 합니다.
3. 결론
@Controller와 @RestController의 차이점은 용도의 차이라고 말할 수 있다고 생각합니다.
@Controller 어노테이션은 공식적으로 Spring 2.5 버전에서 추가되었고, @RestController는 Spring 4.0 버전에서 추가되었습니다.
과거에는 JSP, HTML과 같은 View를 전달해 주었기에 주로 @Controller를 사용했고,
최근에는 Frontend / Backend을 나누어 개발하는 경우가 많기에 Backend에서 Rest Api를 통해 JSON으로 데이터만 전달하기 때문에 편리성을 위해 @RestController를 사용한다고 합니다.
+ 참조 사이트
'⋆ 。゜☁︎ 。⋆ 。゜☾゜。⋆⋆ 。゜☁︎ 。⋆ 。゜☾゜。⋆ > Spring' 카테고리의 다른 글
[SpringBoot] 로그 레벨(Log Level)이란? 로그레벨 설정하기 (0) | 2023.10.19 |
---|---|
[SpringBoot] log4j의 additivity 옵션 (0) | 2023.10.19 |
[SpringBoot] 로그설정 - log4j2 (1) | 2023.10.19 |
[Springboot] Springboot 프로젝트 생성 및 셋팅하기 (1) | 2023.09.24 |
[Spring] @RequestParam을 이용한 값 받아오기 (0) | 2023.08.15 |