MVC (Model, View, Controller)
하나의 서블릿이나, JSP로 처리하던 것을 컨트롤러와 뷰라는 영역으로 서로 역할듯 나눈 것이다.
- 컨트롤러 : HTTP 요청을 받아서 파라미터를 검증하고, 비지니스 로직을 실행한다. 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.
- 모델 : 뷰에 출력할 데이터를 담아둔다. 뷰가 필요한 데이터를 모두 모델에서 담아서 전달 해주기 때문에, 뷰는 비지니스 로직이나 데이터 접근을 몰라도 되고 화면 렌더링만 집중 할 수 있다.
- 뷰 : 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다.
⚠️ 참고
컨트롤러에 비즈니스 로직을 둘 수도 있지만, 그렇게 되면 컨트롤러가 너무 많은 역할을 담당한다.
일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다.
컨트롤러는 비즈니스 로직이 있는 서비스 호출을 담당한다.
MVC 패턴 적용
- 서블릿은 컨트롤러로 사용하고, JSP를 뷰로 사용하여 MVC 패턴 적용
- Model은 HttpServletRequest를 사용한다.
- request 내부 저장소에 .setAttribude()로 보관, .getArrtibute()로 조회 할 수 있다.
컨트롤러
@WebServlet(name = "mvcMemberFormServlet", urlPatterns = "/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
- dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능. 서버 내부에서 다시 호출 발생
/WEB-INF
- 이 경로 안에 JSP가 있으면 외부에서 직접 JSP를 호출할 수 없다. (항상 컨트롤러를 통해서만 JSP 호출가능)
redirect VS forward
- 리다이렉트는 실제 클라이언트(웹 브라우저)에 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청.
- 따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다.
- 그러나 forward는 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 전혀 인지하지 못한다.
MVC 한계
MVC 컨트롤러의 단점
- 포워드 중복
- View로 이동하는 코드가 항상 중복 호출되어야 한다.
- 메서드로 공통화 해도 되지만, 해당 메서드도 항상 직접 호출해야한다.
- viewPath 중복
- prefix : "/WEB-INF/views/"
- suffix : ".jsp"
- 만약 jsp가 아닌 thymeleaf 같은 다른 뷰로 변경하면 전체 코드를 변경해야 한다.
- 사용하지 않는 코드
- 공통 처리가 어렵다.