@MVC 컨트롤러 메서드는 리턴 타입도 다양하게 결정가능. 다행히도 파라미터와 달리 리턴값은 타입하나.

 컨트롤러가 DspatcherServlet에 돌려줘야 하는 정보는 모델과 뷰다. 핸들러 어댑터를 거쳐서 최종적으로 DispatcherServlet에 돌아갈 떄는 ModelAndView타입으로 리턴 값이 전달된다. 드물지만 ModelAndView는 무시하고 HttpServletResopnse에 직접 결과를 넣어 리턴하는 경우도 있다. 

@Controller 메서드의 리턴 타입은 기타 정보와 결합해서 결국 ModelAndView로 만들어진다. 메서드의 리턴 타입을 결정할 때는 ModelAndView에 함계들어갈 정보로 어떤 게 있는지도 함께 고려해봐야 한다. 

 

자동 추가 모델 오브젝트와 자동생성 뷰 이름

다음 네가지 정보는 메서드 리턴 타입에 상관없이 조건만 맞으면 모델에 자동으로 추가된다.

 

-@ModelAttribute 모델 오브젝트 또는 커맨드 오브젝트

 

-Map,Model ModelMap파라미터

 

-@ModelAttribute 메서드

 

-BindingResult

 

컨트롤러에서 어떤 식으로든 뷰 정보를 제공해주지 않는 경우에는 RequestToViewNameTranslator 전략에 의해 자동으로 뷰 이름이 만들어진다. ModelAndView 타입의 오브젝트로 리턴했을 경우에도 역시 뷰 이름이 설정되어 있지 않다면 뷰 이름 자동생성의 대상이 된다.

 

메서드 리턴 타입의 종류

ModelAndView

ModelAndView는 컨트롤러가 리턴해야 하는 정보를 담고 있는 가장 대표적인 타입이다. 하지만 @Controller에는 ModelANdView를 이용하는 것보다 편리한 방법이 많아서 자주 사용 X.

 

String

메서드 리턴타입이 스트링이면 이 리턴 값은 뷰 이름으로 사용된다. 모델 정보는 모델 맵 파라미터로 가져와 추가해주는 방법을 사용.

@RequestMapping("/hello")

public String hello(@RequestParam String name,Model model){

   model.addAttribute("name",name);

   return "hello";

}

모델은 파라미터로 맵을 가져와 넣어주고 리턴 값은 뷰 이름을 스트링 타입을 선언하는 방식은 흔히 사용되는 @Controller메서드 작성 방법. 

 

void

메서드 리턴타입을 아예 void로 할 수있다. 이때는 RequestToViewNameResolver전략을 통해 자동생성되는 뷰 이름이 사용된다. 

 

모델 오브젝트

뷰 이름은 RequestToViewNameResolver로 자동생성하는 것을 사용하고 코드를 이용해 모델에 추가할 오브젝트가 하나 뿐이라면, Model파라미터를 받아서 저장하는 대신 모델 오브젝트를 바로 리턴해도된다.

 

Map/Model/ModelMap

메서드의 코드에서 Map이나 Model,ModelMap 타입의 오브젝트를 직접 만들어서 리턴해주면 이 오브젝트는 모델로 사용된다. 컨트롤러 코드에서 필요한 모델 맵은 파라미터로 받아서 사용하면 편리하다. 따라서 안씀.

 

View

스트링 리턴 타입은 뷰 이름으로 인식한다. 그런데 뷰 이름대신 뷰오브젝트를 사용하고 싶다면 리턴타입을 View로 선언하고 뷰 오브젝트를 넘겨주면 된다.

 

@ResponseBody

@ResponseBody는 @RequestBody와 비슷한 방식으로 동작한다. @ResponseBody가 메서드레벨에 부여되면 메서드가 리턴하는 오브젝트는 뷰를통해 결과를 만들어내는 모델로 사용되는 대신, 메시지 컨버터를통해 바로 HTTP응답의 메시지 본문으로 전환된다.

 다음코드의 메서드에 @ResponseBody가 없다면, 스트링 타입의 리턴값은 뷰 이름으로 인식될 것이다. 하지만 @ResponseBody가 붙었으므로 스트링 타입을 지원하는 메시지컨버터가 이를 변환해서 HttpServletResponse의 출렧스트림에 넣어버린다.

 

@RequestMappin("/hello")

@ResponseBody

public String hello(){

  return "<html><body> Hello Spring </body></html>";

{

@ResponseBody가 적용된 컨트롤러는 리턴 값이 단일 모델 오브젝트이고 메시지컨버터가 뷰와같은 식으로 동작ㄷ한다고 이해할 수있따. 근본적으로 @RequestBody, @ResponseBody는 XML이나 JSON과 같은 메시지 기반의 커뮤니케이션을 위해 사용된다. 

+ Recent posts