mvc 패턴은 서블릿이나 JSP 내부에서 처리하던 모든 로직을 Controller와 View라는 영역으로 역할을 나누는것을 말한다.
컨트롤러 : HTTP 요청을 받아서 파라미터를 검증하고 비지니스 로직을 실행합니다.
그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담습니다.
모델 : 뷰에 출력 할 데이터를 담아둡니다. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비지니스 로직이나 데이터 접근 방식을 몰라도되고 화면 렌더링 방식에만 집중할 수 있습니다.
뷰 : 모델에 담겨 있는 데이터를 사용해서 화면을 그리는일에 집중합니다.
참고로 컨트롤러내부에서 비지니스 로직을 구현할수도있지만 일반적으로는 서비스와 리포지토리로 역할을 구분해서 처리한다. 컨트롤러 안에 비지니스 로직을 담으면 코드 형상 관리에서 crash도 많이 발생하고 불필요한 수정이 발생하기 떄문에 기피해야합니다.
김영한님 강의에서는 아래와 같이 서블릿을 MVC 패턴을 적용해서 코드리팩토링을 진행했다.
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
// setAttribute를 통해서 Model에 데이터를 추가함.
request.setAttribute("member", member);
// 아래 코드에서 dispatcher를 통해서 jsp 파일로 forwarding 시킴.
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
코드에 대한 설명을 약간 하자면 다음과 같다
따라서, 위 코드와 JSP를 이용해서 컨트롤러와 뷰 로직을 분리해서 MVC 패턴을 구현할 수 있다.
하지만, 위 코드에도 단점은 무조건 존재했다.
그 단점은 동일한 코드들이 중복된다는 점이다.
예를 들면, dispatcher는 항상 중복되고 있다.
즉 아래의 코드들이 중복될 수 있다.
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
그리고 사용하지 않는 코드들도 존재하며(HttpServletResponse), 그리고 공통 처리가 어렵다.
따라서, 공통 처리를 할 수 있는 프론트 컨트롤러 패턴을 도입해야하며 스프링 MVC의 핵심 패턴이라고 할 수 있다.
프론트 컨트롤러 패턴은 가장 앞단의 대표 컨트롤러를 두고 공통된 입구를 만드는 패턴이라고 할 수 있다.
프론트 컨트롤러를 도입하지 않는다면 외부의 Http Request 요청은 이곳 저곳에서 처리될 수 있다.
하지만, 가장 앞단에 프론트 컨트롤러를 세워놓고 프론트 컨트롤러에서 뒷단의 컨트롤러로 분배가 된다면 공통 처리도 용이하고 이곳 저곳에서 Http Request가 처리되지 않고 정리할 수 있다
프론트 컨트롤러 패턴의 특징은 아래와 같습니다.
스프링 웹 MVC의 Dispatcher Servlet이 FrontController 패턴으로 구현되어 있다고 함.
해당 포스팅은 아래의 강의를 학습 후 정리한 내용입니다.
김영한님의 스프링MVC1편 1
김영한님의 스프링MVC1편 2