2022-04-19(화)

Front Controller

BoardListController
BoardDetailController
BoardAddController
BoardUpdateController
BoardDeleteController

하나의 서비스가 여러 개의 DAO를 호출하기도 한다

컨트롤러를 좀더 쉽게 통제하기 위해서 컨트롤러의 공통 코드를 빼내서 캡슐화한다.
=> <<Front Controller>> DispatcherServlet

이제 DispatcherServlet한테 요청을 한다

요청을 받은 DispatcherServlet

<<Page Controller>> BoardController
특정 페이지의 요청 처리

Page Controller를 include 시킨다

<<Front Controller>> DispatcherServlet
• 페이지 컨트롤러의 공통 기능 수행
‐ 예외 처리
‐ 뷰 컴포넌트를 실행
‐ 입력값 검증
=> 이게 바로 Front Controller를 만든 이유

class + class + class = component
component + component = Framework
Framework + ⍺ = App.

한 개의 클래스가 하나의 컴포넌트가 될 수 있다
예) 저항 -> 부품, 칩 -> 부품
가장 최소 단위이면서 부품

RAM... 단독적으로 PC에 꽂아서 쓸 수 없음
1개 이상의 클래스로 구성된 컴포넌트의 전형적인 예

component : 1개 이상의 클래스로 구성된 하나의 중간 부품
대표적인 게 LinkedList
중첩 클래스로 Node 라는 클래스를 만들었었음
두 개의 클래스가 합쳐져서 하나의 역할을 수행. 전형적인 컴포넌트.

@SuppressWarnings("serial")

초록색을 호출한다

클라이언트가 뭐라고 요청했는지도 알고 싶음

웹 브라우저가 원하는 자원

html이면 읽어서 던져주면 되고
단순한 파일, html, css, js, 이미지 파일 등 정적자원이라면 그냥 읽어서
실행을 해야 되는 자원이라면 실행 결과를 던져준다

url은 HTTP 프로토콜의 일부

요청 헤더 정보 추출, url 추출 메서드를 구비하고 있지 않다

프로토콜에 대한 응답을 다룰 수 있도록 객체를 실제로 넘긴다

클라이언트 요청을 제대로 다루려면 원래 타입으로 바꾸고 써라

오리지널 service를 오버라이딩하는 것보다 얘를 오버라이딩 하는 게 편함

그 중에서 GET 요청이 들어오는 것만 처리하고 싶음
그럼 doGet을 오버라이딩 한다

초록색 service가 노란색 서비스를 호출한다

http://localhost:8080/app/board/list

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse resp)
      throws ServletException, IOException {
    System.out.println(request.getServletPath()); // /app
    System.out.println(request.getPathInfo()); // /board/list
  }
}

/app
/board/list

url이 유효한지 상관없이 리턴한다

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    System.out.println(request.getServletPath());
    System.out.println(request.getPathInfo());

    String controllerPath = request.getPathInfo();

    RequestDispatcher 요청배달자 = request.getRequestDispatcher(controllerPath);
    System.out.println(요청배달자);

    요청배달자.include(request, response);
  }

http://localhost:8080/app/board/list

유효하지 않은 url은 에러 뜸

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    System.out.println(request.getServletPath());
    System.out.println(request.getPathInfo());

    String controllerPath = request.getPathInfo();

    try {
      RequestDispatcher 요청배달자 = request.getRequestDispatcher(controllerPath);
      System.out.println(요청배달자);

      요청배달자.include(request, response);
    } catch (Exception e) { // 클라이언트가 보낸 url이 유효하지 않으면
      request.setAttribute("exception", e);
      request.getRequestDispatcher("/jsp/error.jsp").forward(request, response);
    }
  }

한글 깨짐

include는 Content-Type을 여기서 설정해야 됨

response.setContentType("text/html; charset=UTF-8");

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    System.out.println(request.getServletPath());
    System.out.println(request.getPathInfo());

    String controllerPath = request.getPathInfo();

    try {
      response.setContentType("text/html; charset=UTF-8");
      RequestDispatcher 요청배달자 = request.getRequestDispatcher(controllerPath);
      System.out.println(요청배달자);

      요청배달자.include(request, response);
    } catch (Exception e) { // 클라이언트가 보낸 url이 유효하지 않으면
      request.setAttribute("exception", e);
      request.getRequestDispatcher("/jsp/error.jsp").forward(request, response);
    }
  }

잘 나옴

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    System.out.println(request.getServletPath());
    System.out.println(request.getPathInfo());

    String controllerPath = request.getPathInfo();

    try {
      response.setContentType("text/html; charset=UTF-8");
      RequestDispatcher 요청배달자 = request.getRequestDispatcher(controllerPath);
      System.out.println(요청배달자);

      요청배달자.include(request, response);

      Exception exception = (Exception) request.getAttribute("exception");
      if (exception != null) { // 페이지 컨트롤러에서 에러가 발생한 경우
        throw exception;
      }
    } catch (Exception e) { // 클라이언트가 보낸 url이 유효하지 않으면
      if (request.getAttribute("exception") == null) {
        request.setAttribute("exception", e);
      }
      request.getRequestDispatcher("/jsp/error.jsp").forward(request, response);
    }
  }

http://localhost:8080/app/board/list

페이지 컨트롤러를 일반 클래스(POJO)로 만들기

Page Controller

<<interface>> Controller

장점
Front Controller가 모든 요청을 받기 때문에 페이지 컨트롤러는 서블릿일 필요가 없다

서블릿 객체가 아니기 때문에 서블릿 컨테이너가 안 만듦
이 클래스의 인스턴스는 서블릿 컨테이너가 자동으로 만들지 않는다
우리가 만들어야 한다
언제?
서버가 스타트했을 때
ContextLoaderListener

이제 페이지 컨트롤러는 더 이상 서블릿이 아니다

애노테이션과 리플렉션 API를 활용하여 페이지 컨트롤러 객체를 자동 생성하기

좋은 웹페이지 즐겨찾기