1 분 소요


View 분리 - V2

String viewPath = "/WEB-INF/views/~~~.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

모든 Controller에서 View로 이동하는 부분에 중복되는 코드를 별도의 View를 처리하는 객체를 만들어서 분리하는게 목적이다.


V2 구조
v2

MyView

public class MyView {
    private String viewPath;

    public MyView(String viewPath) {
        this.viewPath = viewPath;
    }

    public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }    
}

ControllerV2

public interface ControllerV2 {

    MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}

MemberFormControllerV2

@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    return new MyView("/WEB-INF/views/new-form.jsp");
}

각 컨트롤러는 dispatcher.forward()를 생성해서 호출하지 않고, MyView 객체를 생성하고 View 이름만 넣고 반환하면 된다.

MemberSaveControllerV2

@Override
public MyView process(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);

    request.setAttribute("member", member);

    return new MyView("/WEB-INF/views/save-result.jsp");
}

FrontControllerV2

@WebServlet(name = "frontControllerServletV2", urlPatterns = "/front-controller/v2/*")
public class FrontControllerServletV2 extends HttpServlet {

    private Map<String, ControllerV2> controllerMap = new HashMap<>();

    public FrontControllerServletV2() {
        controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
        controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String requestURI = request.getRequestURI();

    ControllerV2 controller = controllerMap.get(requestURI);

    if (controller == null) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    MyView view = controller.process(request, response);
    view.render(request, response);
    }
}


정리

  • 각 Controller를 호출하면 MyView에 View이름을 넣어서 반환해 준다.
  • MyView 생성자를 통해서 MyView 클래스의 필드 인스턴스인 viewPath에 View이름이 저장된다.
  • 마지막으로 view.render()를 호출함으로써 JSP가 실행되게 된다.
  • FrontController의 도입으로 MyView객체의 render()를 호출하는 부분을 모두 일관되게 처리할 수 있다.
  • 각각의 Controller는 MyView객체를 생성만 해서 변환하면 된다.


<출처 : 인프런 - 스프링 MVC 1편 : 백엔드 웹 개발 핵심 기술(김영한)>

댓글남기기