HttpServlet 클래스
HttpServletRequest , HttpServletResponse 객체를 매개변수로 갖고 있다.Servlet 라이프 사이클을 이해하면, 동작 원리를 이해하기 쉽다.
1. 브라우저 요청 -> Servlet 클래스가 로딩, 요청에 대한 Servlet 객체 생성
2. 서버는 init() 메서드를 호출, Servlet 초기화 (서블릿 클래스 로딩 후에는 초기화 작업 없이 바로 호출.)
3. Service() 메서드 호출 => Servlet이 브라우저 요청을 처리하도록 한다.
4. Service() 메서드는 특정 **HTTP 요청을 처리하는 메서드 doGet, doPost 를 호출**합니다.
5. 서버는 destroy() 메서드를 통해 Servlet을 제거한다.
⭐ DispatchServlet 생성 이유
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Rq rq = new Rq(req, resp);
    MemberController memberController = new MemberController();
    ArticleController articleController = new ArticleController();
    // getRequestURI는
    // http://localhost:8081/usr/article/list/free?page=1 에서
    // /usr/article/list/free 부분만 가져온다.
    String url = req.getRequestURI();
    switch (url) {
        case "/usr/article/list/free":    
            articleController.showList(rq);
            break;
        case "/usr/member/login":
            memberController.showLogin(rq);
            break;
    }
}✏ 오답노트
1. break; 문을 빠뜨려서 오류 발생. -> 굉장히 잦은 실수.
2. switch case 분기문에서 url 의 맨 앞 /를 빼먹어서 오류 발생 
  -> req.getRequestURI() 메서드는 /usr/article/list/free 이렇게 가져온다.
📚 개념정리
http://localhost:8080/usr/article/list.jsp
1. request.getContextPath(); => 프로젝트 path 만 가져온다.
  - /project 만 가져온다.
2. request.getRequestURI(); => 프로젝트 + 파일경로까지 가져온다.
  - /usr/article/list.jsp
3. request.getRequestURL(); => 전체 경로를 가져온다.
  - http://localhost:8080/usr/article/list.jsp
4. request.ServletPath(); => 파일명만 가져온다.
  - list.jsp
5. request.getRealPath(); => 절대경로로 가져온다.
  - c:\project\webapp\usr\article
String url =  request.getRequestURI.split("/");
String fileName = url[url.length-1];   // 마지막 인덱스에 접근, list.jsp 를 가져온다.