Spring에서 컨트롤러를 지정해주기 위한 어노테이션은 @Controller와 @RestController가 있습니다. 전통적인 Spring MVC의 컨트롤러인 @Controller와 Restuful 웹 서비스의 컨트롤러인 @RestController의 주요한 차이점은 HTTP Response Body가 생성되는 방식입니다.
1. @Controller(Spring MVC Controller)
[ Controller - View ]
전통적인 Spring MBC의 컨트롤러인 @Controller는 주로 View를 반환하기 위해 사용합니다. 아래와 같은 과정을 통해 Spring MVC Container는 Client의 요청으로부터 View를 반환합니다.
- Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
- Mapping되는 Handler와 그 Type을 찾는 DispatcherServlet이 요청을 인터셉트한다.
- Controller가 요청을 처리한 후 응답을 DispatcherServlet으로 반환하고, DispatcherServlet은 View를 사용자에게 반환한다.
[ Controller - Data ]
하지만 Srping MVC의 컨트롤러에서도 Data를 반환해야는 하는 경우도 있습니다. Spring MVC의 컨트롤러에서는 데이터를 반환하기 위해 @ResponseBody 어노테이션을 활용해주어야 합니다. 이를 통해 Controller도 Json 형태로 데이터를 반환할 수 있습니다.
- Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
- Mapping되는 Handler와 그 Type을 찾는 DispatcherServlet이 요청을 인터셉트한다.
- @ResponseBody를 사용하여 Client에게 json 형태롤 데이터를 반환한다.
@Controller가 Data를 반환하기 위해서는 viewResolver 애신에 HttpMessageConverter가 동작합니다. HttpMessageConverter에는 여러 Converter가 등록되어 있고, 반환해야하는 데이터에 따라 사용되는 Converter가 달라집니다. 단순 문자열인 경우에는 StringHttpMessageConverter가 사용되고, 객체인 경우에는 MappingJackson2HttpMessageConverter가 사용되며, 데이터 종류에 따라 서로 다른 MessageConverter가 작동하게 됩니다. Spring은 클라이언트의 HTTP Accept 헤더와 서버 컨트롤러 반환 타입 정보 들을 조합해 적합한 HttpMessageConverter를 선택하여 이를 처리합니다.
[ Controller 예제 코드 ]
@Controller
@RequestMapping("/user")
public class MVCController{
@Autowired
public MemberService memverService;
@GetMapping("/login")
public String showLoginPage() {
return "/login";
}
@PostMapping("/login")
public String executeLogin(@RequestParam("id") String id,@RequestParam("password") String password){
memverService.executeLogin(id,password);
return "redirect:index";
}
@GetMapping("/myInfo")
public String showMyInfo(Model model,@RequestParam(value="id",required=true)){
UserInfo userInfo = memberService.retrieveUserInfo(id);
model.addAttribute("userInfo",userInfo);
return "/myInfo";
}
@PostMapping("/modifyMyInfo")
@ResponseBody
public UserInfo modifyMyInfo(Model model,@RequestBody UserInfo user){
UserInfo userInfo = memberService.modifyUserInfo(user);
return userInfo;
}
}
위 예제에서는 User가 로그인하고 개인정보를 수정하는 기능에 대해서 구현해 놓았습니다. View를 반환하기 위해서 반환값을 String으로 선언하고 view의 경로를 return해줍니다. 마지막에 작성된 modifyMyInfo는 수정된 user 정보를 반환하기 위해 @ResponseBody를 사용하여 UserInfo를 Json 형식으로 반환하여, 기존에 화면에 데이터만 반환합니다.
2. @RestController(Spring Restful Controller)
[ RestController ]
@RestController는 Spring MVC Controller에 @ResponseBody가 추가된 것입니다. 당연하게도 RestController의 주용도는 Json 형태로 객체 데이터를 반환하는 것입니다. 화면에 데이터만 주로 전달할 때 사용합니다.
- Client는 URI 형식으로 웹 서비스에 요청을 보낸다.
- Mapping되는 Handler와 그 Type을 찾는 DispatcherServlet이 요청을 인터셉트한다.
- RestController는 해당 요청을 처리하고 데이터를 반환한다.
@RestController
@RequestMapping("/user")
public class RestController{
@Autowired
public MemberService memverService;
@GetMapping("/login")
public ModelAndView showLoginPage() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/login");
return mv;
}
@PostMapping("/login")
public ModelAndView executeLogin(@RequestParam("id") String id,@RequestParam("password") String password){
ModelAndView mv = new ModelAndView();
memverService.executeLogin(id,password);
mv.setViewName("redirect:index");
return mv;
}
@GetMapping("/myInfo")
public ModelAndView showMyInfo(@RequestParam(value="id",required=true)){
ModelAndView mv = new ModelAndView();
UserInfo userInfo = memberService.retrieveUserInfo(id);
mv.setViewName("/myInfo");
mv.addObject("userInfo",userInfo);
return mv;
}
@PostMapping("/modifyMyInfo")
public UserInfo modifyMyInfo(Model model,@RequestBody UserInfo user){
UserInfo userInfo = memberService.modifyUserInfo(user);
return userInfo;
}
}
@Restcontroller를 사용하면 Json형태로 데이터를 전달하고자 할 때 @ResponseBody를 선언해 주지 않아도 Json형식으로 반환합니다. 만일 HTML파일을 반환하고 싶다면 ModeAndView 객체를 반환값으로 설정하며, 반환하고 싶은 HTML url을 setViewName으로 설정하고, 반환하고 싶은 데이터를 addObject로 설정하여 반환하면 됩니다.
[ 참고 ]
'개발 > Spring' 카테고리의 다른 글
[Spring] 의존성 주입의 정의 및 의존성 주입 3가지 방식 (생성자 주입, 수정자 주입, 필드 주입) (0) | 2022.04.30 |
---|---|
[Spring Boot] Thymeleaf 사용하기 (0) | 2022.03.06 |
[Spring] @RequestParam과 @PathVariable의 차이는? (0) | 2022.02.20 |
[Spring] SSE(Server-Sent Events) 이해하기[실시간 서버 데이터 구독] (0) | 2022.02.10 |
[Spring Boot] Spring Security 로그인기능 구현하기 (0) | 2022.01.29 |