카테고리 없음

@RestController 와 ModelAndView 그리고 @ModelAttribute

findmypiece 2021. 8. 4. 22:00
728x90

요즘은 백앤드와 프론트앤드를 완전히 나눠서 개발하기 때문에 백앤드에서 ModelAndView 를 사용할 일은 거의 없다. 즉, 백앤드에서는 Api개발에 그외 성능 개선이나 인프라 적인 요소에 집중하게 된다. 하지만 일부 간단한 프로젝트에서는 아직도 백앤드에서 풀스택으로 개발하는 경우가 많으며 그때는 ModelAndView 가 많이 사용된다.

 

이 경우 Controller 에 @RestController를 지정해야 할까 @Controller 를 지정해야 할까? 정석은 api형태의 컨트롤러와 view형태의 컨트롤러를 클래스로 분리해서 각각 @RestController 와 @Controller 를 지정하는 것인데 view형태의 컨트롤러를 사용한다는 것은 이미 소규모 프로젝트라는 말이고 굳이 컨트롤러를 나눠서 작성할 필요까진 없는 경우가 대부분이다.

 

이때는 기본적으로 @RestController 만 지정해도 모두 처리가 가능한데 리턴타입이 ModelAndView 일 경우 view로 이동하고 그 외 타입일 경우 json 문자열로 직렬화를 시도한다.

 

그런데 @RestController 를 지정할 경우 @ModelAttribute 를 사용할 때 주의가 필요하다. 알다시피 @ModelAttribute은 VO, Map 등으로 파라미터를 타입형태로 받을 때 사용되고 기본적으로 파라미터로 넘어온 값을 response에도 포함하기 때문에 파라미터로 넘어온 값을 계속 가지고 이동해야 하는 게시판 리스트에 많이 사용된다.

 

사용방법은 기본적으로 아래와 같다.

@GetMapping("list")
public String getList(
  @ModelAttribute(value="pageModel") PageModel pageModel
  , Model model
){
  model.addAttribute("list", ...);
  model.addAttribute("count", ...);

  return "list";
}

이렇게 되면 Thymeleaf 를 사용하는 기준 list.html 로 이동할 것이고 response 에는 위에서 추가한 list, count 외에 pageModel 이 자동으로 포함될 것이다.

 

그런데 위에서 말했듯이 @RestController를 사용할 경우 리턴타입이 ModelAndView 일 때만 view 로 이동하기 때문에 view로 이동을 원한다면 ModelAndView 를 리턴하도록 아래와 같이 변경해야 한다.

 

@GetMapping("list")
public ModelAndView getList(
  @ModelAttribute(value="pageModel") PageModel pageModel
){
  ModelAndView modelAndView = new ModelAndView("list");
  modelAndView.addObject("pageModel", pageModel);
  modelAndView.addObject("list", ...);
  modelAndView.addObject("count", ...);

  return modelAndView;
}

보편적인 방식으로 처리가 되지 않아 방식을 바꾸긴 했지만 클라이언트에서 넘겨주는 파라미터가 아닌 Model model 를 없앨 수 있어서 오히려 더 직관적인 소스가 되었다.

 

 

 

728x90