LifecycleServlet 클래스를 생성하여 어떤 식으로 어떤 메소드가 실행되는지 확인해보겠습니다.
처음 생성했던 프로젝트인 firstWeb에서 examples 패키지에 LifecycleSerblet 클래스 파일을 생성해줍니다.
이 때 오버라이드할 메소드는 다음과 같습니다.
각각의 메소드가 어떤 순서로 실행되는지 확인해보려 합니다.
HttpServlet의 3가지 메소드를 오버라이딩
- init()
- service(request, response)
- destroy()
생성자
클라이언트가 해당 url로 요청하여, 서버는 그 url을 받아서 LifecycleClass를 실행했습니다.
당연히 메모리 LifecycleClass의 객체가 없을 테니 먼저 그 객체를 생성해야합니다.
그래서 생성자가 먼저 실행됩니다.
init()
생성자 이후에 실행됩니다.
service()
새로고침을 하면 할 수록 service()메소드만 그 횟수만큼 생성됩니다.
새로고침은 새로운 요청이기 때문입니다.
Servlet은 서버에 servlet 객체를 여러 개 만들지 않습니다. (생성자가 한 번만 생기죠)
요청이 여러번 들어오면 요청된 객체가 메모리에 존재하는지 확인 후 있다면 service()만 계속 실행시킵니다.
destroy()
init() 속 print()문을 수정하여 다시 새로고침합니다.
그럼 이전에 쓴 servlet 객체는 더 이상 사용될 수 없습니다.
이 때 destroy() 메소드가 실행됩니다.
다시 새로고침 해보면 수정된 init() 메세지가 뜹니다.
destory()는 과거의 servlet 객체를 제거해주는 역할을 합니다.
Servlet Life Cycle
- WAS는 Servlet 요청을 받으면 해당 servlet이 메모리에 있는 지 확인
- 메모리에 있으면
- 해당 servlet 클래스를 메모리에 올림 (객체생성-생성자)
- init() 메소드 실행
- 없으면
- service() 메소드 실행
- WAS가 종료되거나, 웹 어플리케이션이 새롭게 갱신되면 destroy() 메소드 실행
service(request, response) 메소드
내가 만든 클래스가 service() 메소드를 포함하지 않으면, 나의 부모 클래스의 service() 메소드가 실행됨.
그러니까 HelloServlet.java를 만들었을 때는 doGet()이라는 메소드만 오버라이드 했고
이 service() 메소드는 오버라이드 하지 않았습니다.
그런데 WAS는 매번 service()만 호출합니다. 오버라이드 하지 않았는데도요.
그 이유는 servlet의 부모인 HttpServlet의 service() 메소드가 실행됐습니다.
- HttpServlet의 service() 메소드는 템플릿 메소드 패턴으로 구현되어있습니다.
- 클라이언트 요청이 GET이면, 자신이 가지고 있떤 doGet(request, response) 메소드 호출
- 클라이언트 요청이 POST이면, 자신이 가지고 있떤 doPOST(request, response) 메소드 호출
doGet() 메소드를 실행하려면 다음과 같이 해봅시다.
일단 service()를 주석처리합니다
이후에는 Source -> Override/Implement Methods -> doGet(), doPost() 선택 -> OK
코드는 다음과 같이 수정해줍니다.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doGet(req, resp);
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head><title>form</title></head>");
out.println("<body>");
out.println("<form method='post' action='/firstweb/LifecycleServlet'>");
out.println("name : <input type='text' name='name'><br>");
out.println("<input type='submit' value='ok'><br>");
out.println("</form>");
out.println("</body>");
out.println("</html>");
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doPost(req, resp);
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
String name = req.getParameter("name");
out.println("<h1> hello " + name + "</h1>");
out.close();
}
// protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("service 생성");
// }
링크를 클릭하는 것은 GET 방식으로 서버에게 요청을 보내는 것입니다.
그럼 service() 메소드는 자신의 doGet() 메소드를 실행합니다.
<form> 의 method를 post로 설정하였기에 doPost()가 실행되었습니다.
input의 name 매개변수 속 내용을 읽어오기 위해 req.getParameter("name"); 을 사용했습니다.
같은 url이지만 post 또는 get 방식에 따라 다른 내용이 출력되게 한 것입니다.
+) Run on Server 실패 시
Run on server하려는데 8005, 8080 포트를 종료하거나 포트 번호 바꾸라고 해서 종료부터 해보았다.
두 포트가 같은 PID를 가지고 있어서 종료하면 톰캣 자체도 그대로 끝나서 서버를 열 수 없었다.
그래서 톰캣을 다시 열었는데 그럼 또 두 포트 모두 다 열려있어서 에러 뜬다.
그래서 포트 번호를 바꾸기로 했다.
하단 창에서 Server의 톰캣을 더블클릭하여
각 포트 번호를 다 바꿔준 뒤 실행하니 문제 없었다.
'Web > Java+Spring' 카테고리의 다른 글
JSP (0) | 2021.05.08 |
---|---|
Request, Response (0) | 2021.05.06 |
Servlet (0) | 2021.05.05 |
JAVA 웹 어플리케이션 (HttpServlet) 컴파일 및 실행 (0) | 2021.05.05 |
Apache Tomcat WAS 설치 (0) | 2021.05.05 |