Goal
- Web Service의 기본적인 동작 과정을 이해한다
- Servlet을 이해한다
Servlet이란
Servlet의 개념
웹 기반의 요청에 대한 동적인 처리가 가능한 하나의 클래스
- Server Side에서 돌아가는 Java Program
- 개발자가 작성하는 부분
Servlet의 기본적인 동작과정

- Web Server는 HTTP Request를 Web Container(Servlet Container)에게 위임한다- web.xml설정에서 어떤 URL과 매핑되어 있는지 확인
- 클라이언트(browser)의 요청 URL을 보고 적절한 Servlet을 실행
 
- Web Container는 service() 메소드를 호출하기 전에 Servlet객체를 메모리에 올린다- Web Container는 적절한 Servlet 파일을 컴파일(.class 파일 생성)한다
- .class 파일을 메모리에 올려 Servlet 객체를 만든다
- 메모리에 로드될 때 Servlet객체를 초기화하는 init()메소드가 실행된다
 
- Web Container는 Request가 올 때 마다 thread를 생성하여 처리한다.- 각 thread는 Servlet의 단일 객체에 대한 service() 메소드를 실행한다
 
- Servlet Program에서 Thread의 역할- Thread의 역할: Servlet의 doGet()또는 doPost()를 호출
- Web Container(Servlet Container)는 thread의 생성과 제거를 담당한다- 하지만 thread의 생성과 제거의 반복은 큰 오버헤드를 만든다
- 이를 위해서 Tomcat(WAS)는 “Thread Pool”이라는 적절한 매커니즘을 사용해서 오버해드를 줄인다
 
- 즉, WAS는 Servlet의 Life cycle을 담당한다- 웹 브라우저 클라이언트의 요청이 들어왔을때 Servlet 객체의 생성은 WAS가 알아서 처리한다
- WAS 위에서 Servlet이 돌아다니고 개발자는 이 Servlet을 만들어야한다
 
 
Servlet Life Cycle

- 클라이언트에 요청이 들어오면 WAS는 해당 요청에 맞는 Servlet이 메모리에 있는지 확인한다 - 만약 메모리에 없다면 해당 Servlet Class를 메모리에 올린 후(Servlet 객체 생성) - init() 메소드 실행 후 service() 메소드를 실행
 
- 메모리에 있다면 바로 service 메소드 실행  1 
 2
 3
 4
 5if(메모리에 없음) { 
 // 해당 서블릿 클래스를 메모리에 올림
 // init() 메소드를 실행
 }
 // service() 메소드를 실행
 
- 만약 메모리에 없다면 해당 Servlet Class를 메모리에 올린 후(Servlet 객체 생성) 
- init() - 한 번만 수행된다
- 클라이언트의 요청에 따라 적절한 Servlet이 생성되고
 이 Servlet이 메모리에 로드될 때 init() 메소드가 실행된다
- 역할: Servlet 객체를 초기화
 
- service() - 응답에 대한 모든 내용은 service()메소드에 구현해야한다
- Servlet이 수신한 모든 request에 대해 service() 메소드가 호출된다- HttpServlet을 상속받은 Servlet클래스에서 service()메서드를 오버라이드하지 않았다면, 그 부모인 HttpServlet의 service()가 호출된다
- HttpServlet의 service()메소드는 템플릿 메소드 패턴으로 구현되었다
- service()메소드는 request의 type(HTTP Method: GET, POST, PUT, DELETE)에 따라 적절한 메소드(doGet, doPost, doPut, doDelete)를 호출한다
- 즉, 하위 클래스에서 doGet, doPost등의 메소드를 오버라이드 해두면 HttpServlet의 service()메소드가 요청에 맞는 메소드를 알아서 호출할 수 있게 된다
 
- 메소드가 return하면 thread는 종료된다
 
- destory() - 한 번만 수행된다
- Web Application이 갱신되거나 WAS를 종료할 때 호출된다
- 역할: Servlet 객체를 메모리에서 제거
 
Servlet 메서드 구현 예시
| 1 | // `javax.servlet.http.HttpServlet`를 상속받은 Servlet 클래스 | 
- WAS는 웹 브라우저로부터 요청을 받으면 - 요청할 때 가지고 있는 정보를 HttpServletRequest객체를 생성하여 저장한다
- 웹 브라우저에게 응답을 보낼 때, 사용하기 위한 HttpServletResponse 객체를 생성한다
- 생성된 HttpServletRequest, HttpServletResponse 객체를 Servlet에게 전달한다
 
- 일반적으로 javax.servlet.http.HttpServlet를 상속받은 Servlet클래스를 작성한다 - HttpServletRequest request 파라미터를 통해서 사용자가 입력한 data를 읽는다
- HttpServletResponse 파라지터를 통해서 출력/결과를 생성한다
 
- Servlet 클래스에 doGet() 또는 doPost()중 적어도 하나를 재정의하여 작성한다 - protected doGet()(HttpServletRequest request, HttpServletResponse response){}
- protected doPost()(HttpServletRequest request, HttpServletResponse response){}
 
- HttpServletRequest request 객체 - 사용자가 입력한 내용을 request 객체에 받아온다 - Http 프로토콜의 Request정보를 Servlet에 전달
 
- 헤더 정보, 파라미터, 쿠키, URI, URL, Body의 Stream등을 읽어 들이는 메소드가 있다. 
- getHeader(“원하는 헤더 이름”) - 원하는 헤더 정보를 확인할 수 있다
 
- getParameter() - 이 메소드를 호출하여 parameter값을 가져온다- parameter값은 URL또는 form의 input tag를 통해서 넘어올 수 있다
 
- Ex.  1 
 2String name = request.getParameter("firstname"); 
 int year = Integer.parseInt (request.getParameter("year"));
 
- 이 메소드를 호출하여 parameter값을 가져온다
- getParameterValues() - parameter가 여러 개의 값을 반환할 때 이 메소드를 호출한다. (Ex. checkbox)  1 String languages[] = request.getParameterValues("language"); 
 
- parameter가 여러 개의 값을 반환할 때 이 메소드를 호출한다. (Ex. checkbox)  
 
Servlet Concurrency

- Java 서블릿 컨테니어/ 웹 서버는 일반적으로 멀티 쓰레드 환경이다. - 같은 Servlet에 대한 여러 개의 요청이 동시에 실행될 수 있어 runtime에 따라 결과가 달라질 수 있다
- 즉, Servlet은 메모리에 한 번 올라오고 멀티 쓰레드 환경에서 여러 thread는 하나의 Servlet을 공유하기 대문에 Concurrency Control가 필요하다
 
- Servlet의 service() 메소드 안의 변수 - 정적 변수, 맴버 변수: 공유하는 자원이므로 상호 배제가 필요
- 지역 변수: thread마다 독립적으로 생성
 
Servlet Annotation

- Servlet API 3.0은 javax.servlet.annotation이라는 새로운 패키지를 도입했다.- Tomcat 7이상에서 사용가능
 
- Annotation은 Web Deployment Descriptor파일(web.xml)의 XML 설정을 대체할 수 있다
- Annotation Type- @WebServlet: 서블릿 선언
- @WebInitParam: 초기화 매개 변수 지정
 
- Ex)  1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 public class Simple extends HttpServlet {
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 response.setContentType("text/html");
 PrintWriter out=response.getWriter();
 out.print("<html><body>");
 out.print("<h3>Hello Servlet</h3>");
 out.println(getInitParameter("foo"));
 out.println(getInitParameter("bar"));
 out.print("</body></html>");
 }
 }