서블릿 API
는servlet과 servletConfig 인터페이스를 구현해 제공
하여GenericServlet 추상 클래스
가 이 두 인터페이스의 추상 메서드를 구현한다. 그리고 이 GenericServlet을 다시HttpServlet
이 상속받는다.
( + GenericServlet 추상 클래스는 잘 쓰지 않는다. Http 프로토콜에 대응하는 전용 서블릿인 HttpServlet 추상클래스가 제공되기 때문.)- 기존의
Servlet인터페이스를 구현
해야 했다면해당 인터페이스의 메서드도 같이 구현
해야 했다.
(특히 라이프사이클 메서드라 불리는 init(), service(), destroy()를 일일이 구현해야 했다.)
=> 하지만 해당 추상 클래스(GenericServlet/HttpServlet)를 사용하면 service()만 구현하면 바로 서블릿을 사용할 수 있다.
Servlet 인터페이스
(javax.sevlet 패키지에 선언돼있음) : 모든 서블릿이 구현해야 하는 메서드를 정의하고 있는 인터페이스이다. 서블릿 패키지의 중심이라고 할 수 있는데, 서버가 서블릿을 관리할 수 있도록 서블릿의 생명주기에 필요한 라이프 사이클 메서드(init(), service(), destroy())를 제공하기 때문이다.
주요 메서드
init() : 서블릿 컨테이너가 서블릿을 초기화하기 위해 호출하는 메서드.(단 한번만 실행됨. 이 과정이 성공적으로 끝나야 service()메서드가 이용가능하다.) 참고로 초기화할 때 init()은 서블릿 초기화를 위한 정보를 가진 ServletConfig객체를 파라미터로 전달받아서 서블릿을 초기화한다. service() : 서블릿이 클라이언트 요청(requese)에 응답(response)할 수 있도록 하는 메서드. 컨테이너는 클라이언트 요청이 있을 때 해당 메서드를 실행한다. 그러면 service()메서드는 요청에 따른 메서드를 실행한다.(doGet, doPost, doPut, doDelete) 서블릿은 한 번 불러왔다면 초기화는 더이상 수행되지 않는데, 그렇기 때문에 사용자 요청이 있으면 웹 컨테이너는 사용자의 요청이 맞춰 스레드를 만든다. 그리고 그 스레드를 통해서 service메서드를 실행하고 이미 초기화가 끝나 대기중인 서블릿을 실행한다. destroy() : 서블릿이 더이상 사용되지 않을 때 일반적으로 개발자가 아닌 컨테이너에 의해 호출된다. (단 한번만 실행됨)서비스 메서드 내 모든 스레드가 종료되거나 제한 시간이 지나면 호출된다. 이 메서드를 실행함으로서 서블릿과 관련된 각종 리소스들이 종료된다. getServletConfig() : ServletConfig 객체값을 불러올 수 있도록 하는 메서드다. init()메서드 호출 시, web.xml을 참고하여 서블릿 초기화에 관련된 정보를 저장하는 SservletConfig객체가 파라미터 값으로 전달되는데, 이때 객체값을 불러올 수 있는 메서드이다. getServletInfo() : 서블릿과 관련된 다양한 정보(버전, 저작권자, 작성자)를 문자열로 반환해준다.
내가 이해한 흐름
:init()메서드
는 서블릿 초기화를 해주는데, 이 때 서블릿 초기화를 위한 정보를 가진ServletConfig객체
를 파라미터로 전달받아야 한다. 이 객체를 불러오려면getServletContig()메서드
를 호출하여야 한다. 그리하여 init()메서드가 성공적으로 끝이나면service()메서드
를 이용해 서블릿 이용(요청/응답)을 할 수 있다. 시간이 지나서 서버가 종료되거나 모든 스레드가 종료되면destroy()메서드
가 자동으로 실행되어, 서블릿이 종료된다.
Servlet Config 인터페이스
(javax.sevlet 패키지에 선언돼있음) : 서블릿 컨테이너가 서블릿을 초기화 할 때 필요로 하는 정보를 전달해주기 위해 만든 인터페이스이다. 해당 인터페이스를 기반으로 만든 servletConfig객체는 배포서술자로도 불리는 web.xml을 참고하여 서블릿 초기화를 위한 정보를 저장한다.
GenericServlet 클래스
(javax.sevlet 패키지에 선언돼있음) : 상위 두 인터페이스를 구현하여 일반적인 서블릿 기능을 구현한 클래스이다. Servlet의 라이프사이클 메서드 중 init(), destroy()를 간단하게 제공하므로, 즉 사용자는 service()만 구현하여 서블릿을 간편하게 실행할 수 있다.
HttpServlet 클래스
(javax.servlet.http 패키지에 선언돼있음) : GenericServlet을 상속받아 HTTP 프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행하는 클래스이다. init(), destroy(), service()까지 구현돼 있다. service()가 호출되면서 요청 방식에 따라 doGet()이나 doPost()가 차례대로 호출된다.
protected doGet(HttpServletRequest req, HttpServletResponse resp)
: 서블릿이 GET request를 수행하기 위해 service()를 통해서 호출된다.protected doPost(HttpServletRequest req, HttpServletResponse resp)
: 서블릿이 POST request를 수행하기 위해 service()를 통해서 호출된다.protected Service (HttpServletRequest req, HttpServletResponse resp)
: 표준 HTTP request를 public service()에서 전달받아 doXXX() 메서드를 호출한다.public service (HttpServletRequest req, HttpServletResponse resp)
: 클라이언트의 request를 protected service()에게 전달한다.
흐름정리
: 클라이언트 요청 시public service()메서드
를 먼저 호출한 후, 다시protected service()메서드
를 호출한다. 그런다음 다시 request 종류에 따라doxxx()메서드
를 호출하는 과정으로 실행된다.
- 먼저 Servlet 생명주기를 보자. 여기에서 꼭 알아둬야 할 부분은 Servlet 객체 생성과 init()호출은 단 한 번만 이뤄 진다는 것! destroy()또한 마찬가지!
그렇다면실행이 된 적이 있는 서블릿
이라면,생명주기
에서는계속 service()메서드만 호출되고 이 service()메서드에서 요청에 따른 메서드(doGet() 혹은 doPost()를 실행한다
는 점을 알 수 있다.
- 이제 Servlet 생명주기에서 더 나아가, 전체적인 흐름을 보도록 하자. (핑크색으로 칠해놓은 게, 무조건 서블릿 실행 시 실행되는 것들이다.)
컨테이너가HttpServletRequest, HttpServletResponse 두 객체를 생성
한 후,Web.xml 문서에 따라 그에 맞는 서블릿을 찾았다
면, 해당서블릿 클래스를 로드
하는데 이 때 서블릿에서 사용할객체를 만들고
이 객체를 이용해init()메서드를 호출
한다.
위에서 적은클래스 로드, 서블릿 인스턴스 생성, init()
은 서블릿 생명 주기에서단 한번만 수행되는 것들
이다.(=한 개의 서블릿이 처음 요청될 때만 수행됨)
그리고 많은 요청이 다중으로 들어오면, 이한 개의 인스턴스를 사용
해서새로운 스레드를 생성
하여service()메서드를 실행
한다.
- 처음 요청될 때가 아니라면 어떻게 실행되는지 흐름을 보도록 하자. 여기서 꼭 알아두어야 할 점은 서블릿에 대한
최초 요청
이 있을 때만 서블릿을초기화하는 작업
을 하고, 그 뒤에는최초에 만든 인스턴스 하나
로스레드를 이용
해service()메서드를 실행하여 처리
한다는 점이다.
- 요청을 실질적으로 처리하는 것은,
service()메서드
라는 것을 꼭 알아두자!!!(service()메서드가 요청에 따른 메서드를 실행하기 때문)최초 실행이든 다음 실행이든 service()메서드는 무조건 실행
된다.
HttpServlet 추상 클래스
를 상속받는다.public class 서블릿명 extends HttpServlet {
doGet() 혹은 doPost()메서드의 매개변수
로 HttpServletRequest과 HttpServletResponse를 받아서 사용하면 된다. (굳이 service()메서드는 오버라이딩하여 사용하지 않음)// 'request.위에서 배운 메서드' 혹은 'response.위에서 배운 메서드'로, 요청을 추출 혹은 응답해주면 된다. doGet(HttpServletRequest request, HttpServletResponse response){} doPost(HttpServletRequest request, HttpServletResponse response){}
HttpServletRequest
: 클라이언트가 서버에 보내는 요청정보를 처리하는 객체
클라이언트가 서버로 요청하는 정보
로는 클라이언트의 IP주소, 포트번호 / 클라이언트가 전송한 요청 헤더 정보 / 요청 방식 / 질의(Query) 문자열 등이 있다. 위와 같은 정보를 아래 메서드들을 이용해 출력해보자.ServletResquest 인터페이스
: 네트워크 기반에서 사용되는 기본적인 메소드들로만 구성되어 있음. 나머지는 HttpServletRequest 객체에서 확장 지원하고 있음.//주요 메소드 Object getAttribute(String name) : ServletRequest 객체 안에 등록된 데이터를 추출하여 반환한다. Enumeration getAttributeNames() : ServletRequest 객체 안에 등록된 데이터들의 이름 전부를 하나의 Enumeration 객체에 담아서 반환한다. String getCharacterEncoding() : 클라이언트가 서버에 서비스를 요청할 때 사용한 문자들의 인코딩 문자셋을 반환한다. int getContentLength() : 서비스 요청 시 보낸 요청정보 몸체에 포함된 데이터의 길이를 반환한다. 만약 길이를 알 수 없을 때는 -1를 반환한다. ServletInputStream getInputStream() : 요청정보 몸체로부터 바이너리 데이터를 읽어들이기 위해 한 번에 한 줄씩 읽을 수 있는 ServletInputStream 객체를 반환한다. String getParameter(String name) : 클라이언트가 보낸 질의 문자열 중에서 인자로 지정된 name과 일치하는 것을 찾아 name의 value를 반환한다. Enumeration< String> getParameterNames() : 클라이언트가 서버로 보낸 질의 문자열들의 이름을 하나의 Enumeration 객체에 담아서 반환한다. String[] getParameterValues(String name) : 클라이언트가 서버로 보낸 질의 문자열 중에서 인자로 지정된 name과 일치하는 모든 값을 찾아 하나의 String 타입의 배열에 담아 반환한다. String getProtocol() : 클라이언트가 서버에 서비스를 요청하면서 사용한 프로토콜 정보를 반환한다. BufferedReader getReader() : 요청정보 몸체로부터 문자 인코딩에 따라 텍스트를 읽어들이기 위한 BufferedReader 객체를 반환한다. String getRemoteAddr() : 서버에 서비스를 요청한 클라이언트의 IP 주소를 반환한다. String getScheme() : 서비스 요청 시 사용한 http, https, 또는 ftp 등과 같은 프로토콜 이름을 반환한다. String getServerName() : 서비스를 요청받은 서버의 이름을 반환한다. int getServerPort() : 클라이언트의 서비스를 요청받은 서버 포트 번호를 반환한다. ServletContext getServletContext() : 서버가 시작될 때 웹 애플리케이션 단위로 생성된 ServletContext 객체의 주소를 추출하여 반환한다. void removeAttribute(String name) : ServletRequest 객체에 setAttribute(name) 메소드를 이용하여 등록된 데이터를 삭제한다. void setAttribute(String name, Object o) : 클라이언트의 또 다른 서비스 요청에서도 계속해서 사용하고 싶은 데이터는 서버에 저장해야 하는데 ServletRequest 객체 안에 저장(등록)해준다. void setCharacterEncoding(String env) : 클라이언트가 요청정보 몸체에 포함해서 보내는 문자열들을 지정된 문자셋을 이용해 인코딩해준다.
HttpServletResquest 인터페이스
: 프로토콜에 기반하는 세션이나 쿠키와 같은 정보들을 추출함.//주요 메소드 String getHeader(String headerName) : HTTP 요청 헤더에 지정된 headerName의 값을 문자열로 반환한다. 만일 HTTP 요청 헤더에 headerName의 값이 없으면 null을 반환한다. Enumeration getHeaderNames() : HTTP 요청 헤더에 포함된 모든 헤더의 이름을 Enumeration으로 반환한다. Enumeration getHeaders(String headerName) : HTTP 요청 헤더에 포함된 headerName의 모든 값을 Enumeration으로 반환한다. int getIntHeader(String headerName) : HTTP 요청 헤더에 포함된 headerName의 값을 int로 반환한다. 지정된 headerName의 값을 int로 변환할 수 없을 때 NumberFormat Exception이 발생하고, headerName 헤더가 HTTP 요청 헤더에 없을 때 -1을 반환한다. long getDateHeader(String headerName) : HTTP 요청 헤더에 포함된 headerName의 값을 밀리초로 변환하여 long으로 반환한다. 지정된 header의 값을 int로 변환할 수 없을 때 IllegalArgumentException이 발생하고, headerName 헤더가 HTTP 요청 헤더에 없을 때 -1을 반환한다. String getPathInfo() : 클라이언트가 서비스 요청 시 보낸 요청 URL의 뒷부분에 있는 path 정보를 반환한다. HttpSession getSession() : 서비스를 요청한 클라이언트가 사용하는 HttpSession 객체를 반환한다. 만일 반환할 HttpSession 객체가 없으면 새로 생성하여 반환한다. HttpSession getSession(boolean create) : 서비스를 요청한 클라이언트가 사용하는 HttpSession 객체를 반환한다. 만일 반환한 HttpSession 객체가 없으면 getSession(true)이면 새로 생성하여 반환한다. 그러나 getSession(false)이면 HttpSession 객체를 새로 생성하지 않고 null을 반환한다. String getRequestedSessionId() : 서비스를 요청한 클라이언트가 사용하는 HttpSession의 ID를 반환한다. boolean isRequestedSessionIdValid() : 서비스를 요청한 클라이언트가 사용하는 HttpSession 객체가 유효한지를 판단한다. boolean isRequestedSessionIdFromCookie() : 서비스를 요청한 클라이언트가 사용하는 HttpSession의 ID가 쿠키로 전달되면 true, 그렇지 않다면 false를 반환한다. boolean isRequestedSessionIdFromURL() : 서비스를 요청한 클라이언트가 사용하는 HttpSession의 ID가 URL에 포함되면 true, 그렇지 않다면 false를 반환한다. Cookie[] getCookies() : 서비스를 요청받은 서버가 서비스를 요청한 클라이언트에게 이전에 보낸 모든 쿠키를 추출한다. String getRequestURI() : 클라이언트가 서비스 요청 시 보낸 URL에서 URI 부분만 반환한다. String getQueryString() : 클라이언트가 GET 방식으로 서버에 보낸 질의 문자열들을 모두 추출하여 반환한다. String getMethod() : 클라이언트가 서비스를 요청할 때 요청한 방식의 이름을 반환한다. String getPathTranslated() : 클라이언트가 서비스 요청 시 보낸 URL의 경로 정보를 절대경로(path)로 변경하여 반환한다.
HttpServletResponse
: 서버가 클라이언트로 보내는 응답정보를 처리하는 객체
ServletResponse 인터페이스
: 일반적인 네트워크 통신에서의 응답 관련 메소드 제공//주요 메소드 PrintWriter getWriter() : 서비스를 요청한 클라이언트와 서버 간에 연결된 PrintWriter 객체를 생성하여 반환한다. void setBufferSize(int size) : 출력스트림의 버퍼 크기를 설정한다. void setCharacterEncoding(String charset) : 응답정보 인코딩에 사용할 문자를 설정한다. void setContentLength(int len) : 응답정보의 데이터 길이를 설정한다. void setContentType(String type) : 응답정보의 데이터 형식(MIME 타입)을 설정한다. void setLocale(Locale loc) : 클라이언트가 사용하는 언어, 국가코드 등 클라이언트의 환경을 설정한다.
HttpServletResponse 인터페이스
: HTTP 통신 기반의 응답 관련 메소드 확장 제공( ex : 쿠키 설정, HTTP 응답 헤더 설정 등)//주요 메소드 void addCookie(Cookie cookie) : 인자값으로 주어진 쿠키를 응답정보의 헤더에 추가한다. 쿠키는 응답정보의 Set-Cookie 헤더의 값으로 추가되어 클라이언트로 전송된다. String encodeRedirectURL(String url) : 클라이언트와 서버 간 세션이 유지되는 상태에서 브라우저 쿠키를 지원하지 않을 때 주어진 URL 뒤에 세션 아이디를 추가하고 인코딩하여 요청을 재전송한다. String encodeURL(String url) : 주어진 URL에 세션 아이디를 추가하여 인코딩해서 반환한다. void sendRedirect(String location) : 응답을 클라이언트가 요청한 URL이 아니라 sendRedirect()에 주어진 URL로 재전송한다. 매개변수 location은 절대 URL이나 상대 URL로 지정한다. 이 메소드는 서버의 특정 자원이 다른 URL로 이동할 때 사용할 수 있는 메소드이다. public void setDateHeader(String name, long date) : 날짜를 밀리 초로 변환하여 주어진 이름과 날짜를 응답정보 헤더에 설정한다. public void setHeader(String name, String value) : 응답정보의 헤더에 주어진 이름과 값을 설정한다. public void setIntHeader(String name, int value) : 주어진 이름과 정수값을 갖도록 응답정보 헤더에 추가한다. public void setStatus(int sc) : 응답으로 전송될 HTTP 응답에 대한 상태코드를 설정한다.
DD설정(Web.xml)
: Deploy(배포)할 때 Servlet의 정보를 설정해준다.
브라우저가 Java Servlet에 접근하기 위해서는 WAS(ex : Tomcat)에 필요한 정보를 알려줘야, 해당하는 Servlet을 호출할 수 있다.
- 정보 1 : 배보할 Servlet이 무엇인지 / 정보 2 : 해당 Servlet이 어떤 URL에 매핑되는지
<web-app> <!-- 1. aliases 설정 --> <servlet> <servlet-name>welcome</servlet-name> //2. 해당 클래스의 <servlet-class>servlets.WelcomeServlet</servlet-class> //1. 실제 클래스 이름 설정. ex ) 패키지이름.클래스이름 </servlet> <!-- 2. 매핑 --> <servlet-mapping> <servlet-name>welcome</servlet-name> <url-pattern>/welcome</url-pattern> </servlet-mapping> </web-app>
https://sgcomputer.tistory.com/226
https://loco-motive.tistory.com/2
https://kgvovc.tistory.com/31?category=957989
https://chicken-park.tistory.com/10
https://sgcomputer.tistory.com/232