https://hoestory.tistory.com/12 이곳에서 보면

String path = "경로";
RequestDispatcher dispatcher = request.getRequestDispatecher(path);
dispatcher.forward(request, response);

이 코드들이 controller마다 중복되어 나타나고 깔끔하지 않다.

그래서 깜끔하게 분리하기 위해 view를 분리한다.

프론트 컨트롤 실행 순서(view 분리)

  1. 클라이언트가 FrontController에게 HTTP 요청을 한다.
  2. 요청을 받은 FrontController은 매핑 정보를 조회하여 컨트롤러를 조회한다.
  3. 조회한 컨트롤을 호출하고 호출한 컨트롤러에서 뷰를 반환 받는다.
  4. 반환받은 뷰를 호출한다.
  5. jsp forward를 하고 클라이언트에게 응답한다.

분리한 뷰

public class MyView {

    private String path;

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

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


  public interface Controller {

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

Controller

public class MemberInputController implements Controller {

    @Override
    MyView process(HttpServletRequest request, HttpServletResponse response)
                                thows ServletException,IOException {
            MyView view = new MyView("/WEB-INF/view/input.jsp");
            return view;
 }


 public class MemberSaveController implements Controller {
         private MemberRepository memberRepository = MemberRepository.getInstance();
         @Override
        MyView process(HttpServletRequest request, HttpServletResponse response)
                                thows ServletException,IOException{
                String name = request.getParameter("name");
                int age = Integer.parseInt(request.getParameter("age"));

                Member member = new Member(name,age);
                memberRepository.save(member);
                request.setAttribute("member",member);

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


 public class MemberListController implements Controller {
     private MemberRepository memberRepository = MemberRepository.getInstance();
    @Override
    MyView process(HttpServletRequest request, HttpServletResponse response)
                                thows ServletException,IOException{
              List<Member> members = memberRepository.findAll();
              request.setAttribute("members", members);
              return new MyView("/WEB-INF/view/members.jsp);
 }

위에 코드들은 보면 프론트 컨트롤 개념 및 예제(프론트 컨트롤러 도입)에서 중복적으로 적혀있던 path와 dispatcher.forward가 없다 MyView 클래스에 render라는 함수로 dispatcher.forward를 호출하는 코드를 작성하여 중복을 줄였다.

FrontController

@WebServlet(name="frontController", urlPatterns="/frontcontroller/*")
public class FrontController extends HttpServlet {
    private Map<String, Controller> controllerMap = new HashMap<>();

    public FrontController() {
        controllerMap.put("/frontcontroller/input", new MemberInputController());
        controllerMap.put("/frontcontroller/save", new MemberSaveController());
        controllerMap.put("/frontcontroller/members", new MemberListController());
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
                        throws ServletException, IOException {
            // localhost:9090/frontcontroller/members
            // requestURI => /frontcontroller/members
            String requestURI = request.getRequestURI();


            // Controller controller = controllerMap.get("/frontcontroller/members");
            // => Controller controller = new MemberListController();
            Controller controller = controllerMap.get(requestURI);

            // 그럼 controller은 MemberListController이기 때문에 controller.process는
            // 즉 MemberListController.process와 같다
            // 그러므로 뷰에 반환 되는것은 new MyView("/WEB-INF/view/members.jsp");가 반환

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

            //view 생성자의 매개변수에 경로가 들어와 path는 /WEB-INF/view/members.jsp로 되어있다.
            // render은 forward하는거라 해당 경로로 forward해준다.
            view.render(request, response);
           }
    }

정리

프론트 컨트롤 개념 및 예제(View 분리)는 프론트 컨트롤 개념 및 예제(프론트 컨트롤러 도입) 부분의 각 컨트롤러에서 path와 forward하는 부분이 중복되어  MyView로 별도로 빼서 작성해서 코드의 중복성을 제거하였다.

 

밑으로 내려갈수록 발전된 프론트 컨트롤 패턴 활용

프론트 컨트롤러 도입 - https://hoestory.tistory.com/12

view분리 - https://hoestory.tistory.com/13

Model 추가 - https://hoestory.tistory.com/17

단순하고 실용적 컨트롤러 - https://hoestory.tistory.com/19

유연한 컨트롤 -