발표자료 4 ~ 7 단원 내용 중 ...
Servlet
최초 클라이언트의 요청이 있기 전에 서블릿은 항상 로딩되고 초기화됩니다. 로딩되는 시기는 컨테이너 시작 (즉, 톰캣이 실행될 때) 이루어집니다.
그리고 이제 클라이언트 요청을 받았을 때 흐름순서를 보면,
- 클라이언트 사용자쪽에서 URL을 입력하면 HTTP Request가 servlet Container로 전송합니다.
- 컨테이너는 HttpServletRequest와 HttpServletResponse 두 개의 객체를 생성합니다.
- 그리고 URL을 분석하여 어떤 서블릿을 요청했는지 파악하고 해당 서블릿을 처리할 스레드를 생성해서 request와 response 객체 참조를 넘깁니다.
- 컨테이너는 해당 서블릿 service() 메소드를 호출하여, service() 메소드는 doGet()고 doPost()를 자동 호출하는데, 브라우저에서 지정한 방식에 따라 둘 중에 하나를 선택해서 호출합니다.
- doGet() 메소드는 동적 페이지를 생성한 후, HttpServletResponse 객체에 응답을 보냅니다.
- 응답이 끝나면 HttpServletRequest와 HttpServletResponse 두 객체를 소멸시킵니다.
이런 서블릿에 관련된 것들은 모두 javax.servlet 이나 javax.servlet.http 둘 중 하나입니다.
http와 관련이 있는 것들은 javax.servlet.http이고 나머지는 javax.servlet입니다.
자바 서블릿 클래스는 Servlet 인터페이스를 구현해야 합니다. 이 Servlet은 서블릿 컨테이너가 서블릿에 대해 호출하는 메소드 5가지를 정의한 인터페이스입니다. 굵은 표시로 되어있는 것이 생명주기 메소드입니다.
GenericServlet이랑 HttpServlet은 추상 클래스로
- genericServlet은 대부분 서블릿의 서블릿 행위 라고 하는 것들이 여기서부터 나왔다는 것
- http는 http적인 측면을 반영하기 위해서 service()메소드를 재정의한 것입니다. 이 메소드는 오로지 http request와 response만 받아드립니다.
마지막으로 Myservlet은 이런 상위 클래스의 메소드를 상속받음으로써, 여기선 doGet()이나 doPost() 메소드를 재정의하기만 하면 됩니다.
그래서 총 앞의 흐름대로 이야기를 하면
- 컨테이너가 처음 init() 메소드를 호출합니다. 여기서 init()을 재정의하지 않으면 아까 말한 '서블릿 행위'인 genericServlet의 init()을 호출합니다.
- 그 다음 클라이언트의 요청이 들어오면 새로운 스레드를 만들어서 service()메소드를 호출합니다. 이것도 재정의하지 않으면 httpServlet의 service()메소드가 실행됩니다.
- 그리고 Service()메소드에서 재정의한 doGet()이나 doPost()둘 중 하나를 실행하는 것입니다.
이렇게 앞에 나오는 그림이나 글로 봤을 때 이해는 되지만 너무 추상적인 느낌이 들고, 메소드들을 직접 확인해보고 싶었습니다.
그래서 처음 초기화하는 init() 메소드부터 확인을 해봤습니다.
이 생성자의 실행은 단지 서블릿이 “존재하지 않음” 상태에서 “초기화됨”상태로 옮겨감을 의미합니다. 즉, 클라이언트의 요청에 서비스할 준비가 되었다는 뜻입니다.
그리고 이 생성자는 단지 객체를 만드는 것이지 서블릿을 만드는 것이 아닙니다. 서블릿이 되기 위해서는 서블릿적인 것을 내려받아야하는데, 쉽게 말해서 자기 명함을 갖고 있는 정식 서블릿이 되려면 2가지가 필요합니다.
그 2가지는, ServletConfig와 ServletContext 파라미터 입니다.
이 두가지에 대해서는 뒷부분에 더 자세히 나오지만 일단 필요한 부분만 먼저 이야기하자면, ServletConfig에서 'config'는 설정의 뜻으로, 서블릿마다 설정했던 값을 뜻합니다. 이 ServletConfig를 통해 서블릿 이름, 서블릿 서블릿 초기 매개변수 값, 서블릿 환경 정보 등을 얻을 수 있습니다.
그래서 다시 돌아와서 서블릿이 되기 위해서는, 서블릿을 설정하는 servletConfig 필요합니다.
컨테이너가 서블릿을 초기화할 때, 사실 init()메소드를 먼저 실행하여 존재하지 않음에서 초기화된 서블릿 객체를 만들고, 단지 객체인 것을 그 다음 init(ServletConfig) 메소드를 호출하여 리얼 정식 서블릿을 생성합니다.
서블릿마다 하나씩 ServletConfig를 생성하는데, 컨테이너는 DD에서 서블릿 초기화 파라미터를 읽어서 이 정보를 이름, 쌍으로 해서 ServletConfig로 넘겨줍니다. 그 다음에 ServletConfig를 서블릿의 init()메소드에 제공합니다.
여기서 ServletConfig를 사용할 수 있는 이유는 앞에서 Servlet 인터페이스 부분을 보면 getServletConfig() 메소드가 있는데, 이 메소드가 리턴한 ServletConfig 객체에 대한 참조로 ServletConfig의 메소드를 호출할 수 있습니다.
이렇게 흐름의 첫 번째인 init()에 대한 것을 봤습니다.
이제는 마지막 2~3번째 service()를 호출하고 실행이 되어서 재정의한 doGet()과 doPost()의 실행에 대한 것을 보겠습니다.
httpServlet의 service()메소드 내용입니다. 클라이언트가 날린 http 메소드가 무엇인지 보고 메소드 종류에 따라서 그 메소드를 호출합니다. 그래서 service()를 호출해서 doGet()이든 doPost()든 실행하는 것입니다.
여기까지 코드를 직접 보면서 흐름 이해를 해봤고 그 다음에는 doGet()과 doPost()의 인자로 request와 response객체의 참조를 넘긴다고 했는데 이 두 객체를 가지고 있다는 것이 무엇을 의미하는지 확인해봤습니다.
httpServletRequest 인터페이스는 http 프로토콜에 관련된 메소드들이 추가되어 있습니다. 서블릿이 클라이언트/브라우저와 대화하기 위한 것들이고 httpServletResponse 인터페이스는 http에 관련된 오류, 쿠키, 헤더 정보에 대한 메소드들이 추가되어있습니다.
이 2개의 인터페이스는 책에 따르면,,
이 2개의 인터페이스는 누가 구현하나? API에 구현된 클래스가 있나?
그 답은 '컨테이너'이고 '없습니다.' 입니다. 컨테이너 벤더가 구현하는데 어떻게 되는지 신경 쓰지 마세요.!
요점은 컨테이너가 넘겨준 객체에서 어떤 메소드를 호출할 수 있는가를 아는 것입니다.
Request를 먼저보면, index.html에서 네 개의 옵션 값 중 사용자가 선택한 값 하나를 color라는 이름의 파라미터로 전송을 합니다.
전송 method 방식은 post로 하고 MyServlet의.post()메소드를 보면 request.getParameter()폼에 있는 이름과 맞게 color라고 작성해주고 선택한 값이 들어가게 됩니다.
이 예시 말고도, 파라미터 값이 여러개일 경우 등 더 있지만 결국에는 request는 클라이언트의 요청을 처리해주는 것입니다.
이제는 response는 클라이언트로 돌려보내는 것입니다. 이 정보를 분석해서 브라우저는 화면을 출력합니다. Response 객체는 제가 언급하고 싶은 것 하나가 setContentType()메소드 입니다.
이 contentType은 무엇을 의미하냐면, 브라우저에게 지금 내려보내는 것이 무엇이다라는 것을 알려주는 것입니다. 그래야 브라우저가 이예 대비하여 여기서는 html을 화면에 그릴 준비를 합니다. 이 contentType은 HTTP 응답에 반드시 포함되어야 하는 HTTP 헤더 정보입니다.
그리고 요청에 대한 응답을 누가할지 선택할 수도 있습니다.
요청을 완전히 다른 URL로 방향을 바꿀 수도 있고, 웹 애플리케이션에 있는 다른 컴포넌트(JSP)에게 처리를 위임할 수도 있습니다.
리다이렉트에서는 방향을 바꾸겟다고 판단했다면, sendRedirect()메소드만 호출하면 됩니다.
디스패치는 다른 컴포넌트, JSP로 작업을 넘기는 것의 코드로 RequestDispatcher를 사용합니다.
'IT > Servlet & JSP' 카테고리의 다른 글
[Mini_WAS] WAS만들기 - 중간점검 (0) | 2020.12.02 |
---|---|
[Servlet & JSP] 3. 속성과 리스너 (0) | 2020.11.09 |