서블릿(Servlet) 구현
서블릿 API 문서
- 서블릿 구현시 객체를 따로 만들 필요 없이 WAS에서 제공하는 서블릿 API를 사용하면된다.
- 즉, 이미 구현 되어 있는 서블릿 API를 상속받거나 필요한 메소드를 재정의해야한다.
API를 제대로 활용하려면 해당 문서를 참고해야한다.
서블릿 API 문서를 찾아보자
http://tomcat.apache.org/톰캣 사이트 접속
서블릿 클래스 간의 관계
서블릿 구현시 반드시 'HttpServlet' 클래스를 상속받아야한다.
HttpServlet 클래스에는 웹 클라이언트 요청이 있을때 해당 서블릿을 실행하는 모든 조건이 있다.
HttpServlet 은 GenericServlet 클래스를 상속 받고 Serializable, Servlet, ServletConfig인터페이스를implement하고있다.
Servlet 인터페이스
- 프로그램을 개발할 때 반드시 구현해야하는 메소드를 선언하고 있는 인터페이스
- init(), service(), destroy(), getServletConfig(), getServletInfo() 등 서블릿 프로그램 실행의 생명주기와 연관된 메소드 5개를 선언하고 있다.
GenericServlet 클래스
- servlet 인터페이스를 상속하여 서버단의 애플리케이션으로서 필요한 기능을 구현한 추상클래스 이다.
- service() 메소드를 제외한 모든 메소드를 재정의하여 적절한 기능으로 구현하였다.
HttpServlet 클래스
- GenericServlet 클래스를 상속하여 service() 메소드를 재정의 함으로써 HTTP 프로토콜에 알맞은 동작을 수행하도록 구현한 클래스이다.
즉, HTTP 프로토콜을 기반으로 브라우저로부터 요청을 전달받아서 처리하도록 하는 클래스이다. - service() 메소드에는 요청방식(GET 또는 POST)에 따라 doGet(), doPost() 등 정해진 사양으이 메소드가 호출되도록 구현되어 있다.
- 반드시 재정의 해야하는 메소드 없음.
어떤 요청 방식을 지원하는 서블릿인지에 따라서 필요한 메소드를 재정의하여 구현한다.
서블릿 작성
1. [java resources-src]에서 패키지를 만들기
2. FirstServlet이라는 클래스를 만들기
3. HttpServlet 상속받기
4. init(), service() 메소드 재정의 하기
서블릿 실행 순서
- java EE 기반 프로그램은 실행의 흐름을 '컨테ㅔ이너가 제어' 한다.
이처럼 개발자가 아닌 제3자가 실행의 흐름을 제어하는 것을 IoC(Inversion of Control) 이라고 한다. - 서블릿도 IoC에 속한다.
따라서 애플리케이션 컨테이너 가 프로그램을 어떤 순서로 동작시키는지 알고 순서에 맞게 개발해야한다.
- 클라이언트로 부터 처리 요청 받음
요청정보의 헤더 안에 있는 URI를 분석하여 요청받은 페이지가서블릿이버 서블릿컨테이너에 처리를 넘긴다.
요청 받은 서블릿을 WEB-INF/classes 또는 WEB-INF/lib에서 찾아서 실행 준비 한다. - 최초의 요청 여부 판단
실행할 서블릿 객체가 메모리에 없으면 최초의 요청이고, 이미 있으면 최초의 요청이 아닌 것으로 판다. - 서블릿 객체 생성
요청 받은 서블릿이 최초의 요청이라면 해당 서블릿을 메모리에 로딩하고 객체를 생성한다.
서블릿은 최초의 요청이 들어왔을때 한번만 객체를 생성하고 이때 생성된 객체를 계속 사용한다. - init() 메소드 실행
서블릿 객체가 생성된 다음에 호출되는 메소드.
주로 서블릿 객체의 초기화 작업이 구현되어 있다. - service() 메소드 실행
실행하는 서블릿의 요청 순서에 상관없이 클라이언트의 요청이 있을때마다 자동으로 실행된다.
실제 서블릿에서 처리해야하는 내용이 구현되어있다.
sevice() 메소드가 끝나면 서버에서의 실행은 끝난다.
서버 프로그램의 실행이 완료된 후에는 서블렛 컨테이너가 실행결과를 웹서버에 전달하고 웹서버는 서비스를 요청한 클라이언트에게 응답한다.
이로써 웹에서 하나의 요청에 대한 처리가 완료된다.
콜백 메소드와 서블릿 객체의 생명주기
- 콜백 메소드(callback method)란 어떤 객체에서 어떤 상황이 발생하면 컨테이너가 자동으로 호출하여 실행되는 메소드를 의미한다.
- 콜백 메소드들이 서블릿을 실행한다.
init(), service(), destroy()가 콜백 메소드에 속한다.
메소드이름 | 실행 시점 | 실행횟수 | 기능구현 |
init() | 클라이언트로부터 최초로 서블릿 요청이 있을때 실행 | 1 | 초기화 작업 |
service() | 클라이언트로부터 요청이 있을 때마다 실행 | n | 실제 서블릿이 처리해야 하는 작업 |
destroy() | 서블릿 객체가 메모리에서 삭제될 때 실행(서비스나 서버 중지 시) | 1 | 자원 해제 작업 |
서블릿 객체의 생성
- 서버 입장에서 최초로 서블릿 요청이 있을때(메모리에 서블릿 객체가 없는 경우), 해당 서블릿 객체를 메모리에 생성.
- 최조 요청 때 생성한 서블릿 객체를 재사용하기 때문에 처리속도, 메모리 부분에서 효율적이다.
- init() -> service() 순으로 메서드 실행
서블릿 객체의 삭제
- 서버를 중지시켜 웹 애플리케이션 서비스를 중지할때 서블릿 객체는 삭제된다.
- destory() 메서드 실행
서블릿(Servlet) 실행
- /WEB-INF는 웹서버가 사용하는 파일이 들어있는 중요한 디렉터리이다.
따라서 외부에서 클라이언트가 곧바로 접근할 수 없다.
[예시]
/WEB-INF에 test.jsp 파일을 만들고 서버를 실행하면 '404 Not Found' 응답을 받는다.
즉, /WEB-INF 디렉터리 자체가 서버에서 서비스 되고 있지 않다는 말이다.
그렇다면 어떻게 /WEB-INF에 있는 것을 어떻게 서비스할까?
클라이언트가 서블릿에 접근하여 서비스 결과값만 받아 갈 수 있도록 서버에서 설정해주어야한다.
web.xml 과 어노테이션(annotation)을 이용하여 서블릿 접근 경로를 지정할 수 있다.
web.xml 설정을 통해접근
안 배움(책 P.82)
@WebServlet 을 통해 접근
- 어노테이션을 통해 접근하려면 서블릿의 클래스 선언부 앞에 @WebServlet(접근 시 사용한 URI)를 지정하면된다.
서블릿이 실행되고 어노테이션으로 설정한 URI에 잘 접근하는 것을 확인할 수 있다.
요청 방식에 따른 실행
서블릿의 실행 순서에 따라 서블릿이 실행될 때 service()메소드가 자동으로 실행된다는 것을 배웠다.
그래서 HttpServlet 클래스에 구현된 service()메소드를 재정의하여 메소드의 몸체를 구현해야한다.
그런데 service() 메소드를 재정의하지 않을때가 있다. 이는 HttpServlet에서 구현된 service() 메소드를 그대로 실행하고 싶을때이다.
그렇다면 HttpServlet에는 service() 메소드가 어떻게 구현되어 있는지 알아보자
⓵ protected void service(HttpServletRequest req, HttpServletResponse resp)
⓶ public void service(ServletRequest req, ServletResponse resp)
- ⓶번 형태의 service()
서블릿 요청이 있을 때마다 실행되는 메소드는 ⓶번 형태의 service()이다.
그런데 ⓶ 형태의 service()는 단순히 같은 객체에 있는 ⓵번 형태의 service()를 호출만 해준다. - ⓵ 형태의 service()
⓵ 형태의 service() 메소드는 클라이언트의 요청에 따라 서로 다른 메소드를 호출하도록 구현되어 있다.
⓵ 형태의 service() 메소드는 요청 방식 정보를 추출한 후 추출된 요청 방식 정보에 따라 서로 다른 메소드를 호출하도록 구현되어 있다.
접근자와 타입 | 메소드 |
protected void | doDelete(HttpServletRequest req, HttpServletResponse resp) |
doGet(HttpServletRequest req, HttpServletResponse resp) | |
doHead(HttpServletRequest req, HttpServletResponse resp) | |
doOptions(HttpServletRequest req, HttpServletResponse resp) | |
doPost(HttpServletRequest req, HttpServletResponse resp) | |
doPut(HttpServletRequest req, HttpServletResponse resp) | |
doTrace(HttpServletRequest req, HttpServletResponse resp) |
get방식으로 요청했다면 doGet() 메소드를 호출한다고 생각하면된다.
만약 똑같은 URI 요청을 요청방식에 따라 서로 다르게 동작하게 하려면 service()메소드를 재정의 하지말고
HttpServlet 클래스의 service()메소드가 실행되도록 한다음 doGet() 또는 다른 메소드 등이 실행되도록 이 메소드들을 재정의하여 구현 하면 된다.
웹 화면에서 어떤 것을 작성하여 서버에 제출하는 서비스의 경우 한번 제출한 산태에서 웹 브라우저 화면에 새로고침 버튼을 누르면 두번 제출되는 사례가 있다.
이런 경우는 서버에 제출시 POST 방식을 요청하고, doPost()메소드에 서비스 처리를 구현 하면된다.
'Servlet&JSP' 카테고리의 다른 글
[Tomcat / Oracle]DB 연동하기 (0) | 2020.01.06 |
---|---|
응답정보 처리 HttpServletResponse / 요청 정보 처리HttpServletRequest (0) | 2020.01.06 |
웹 애플리케이션 접근 / 위치 / 구조 / web.xml / 서블릿 디렉터리 (0) | 2020.01.05 |
JAVA와 Web (0) | 2020.01.02 |
서비스 중인 서버 확인 / 서버 주소 분석 (0) | 2020.01.02 |