서블릿 컨텍스트
서블릿 컨테이너 (예 : Apache Tomcat )가 시작되면 모든 웹 애플리케이션을 배치하고로드합니다. 웹 애플리케이션이로드되면 서블릿 컨테이너는 ServletContext한 번 작성 하여 서버의 메모리에 유지합니다. 웹 응용 프로그램의 web.xml및 포함 된 모든 web-fragment.xml파일을 구문 분석하고, 각되고 <servlet>, <filter>및 <listener>발견 (또는 각 클래스는 주석 @WebServlet, @WebFilter및 @WebListener각각) 한 번 인스턴스화하고 서버의 메모리에 저장도된다. 인스턴스화 된 각 필터에 대해 해당 init()메소드는 new로 호출됩니다 FilterConfig.
A는 때 Servlet가 <servlet><load-on-startup>나 @WebServlet(loadOnStartup)보다 더 가치 이상을 0, 다음의 init()방법은 새로운으로 시작하는 동안 호출됩니다 ServletConfig. 해당 서블릿은 해당 값으로 지정된 순서대로 ( 11 일, 22 일 등) 초기화됩니다 . 동일한 값 이상의 서블릿 지정되면 그들은에 나타나는 경우, 그 다른 서블릿 각각 동일한 순서로 로딩 web.xml, web-fragment.xml또는 @WebServlet클래스로드. "시작시로드"값이 없으면 init()HTTP 요청이 해당 서블릿을 처음으로 칠 때마다 메소드가 호출됩니다.
서블릿 컨테이너가 위에서 설명한 모든 초기화 단계로 완료 ServletContextListener#contextInitialized()되면이 호출이 호출됩니다.
아래 서블릿 컨테이너 닫힌다, 그것은 모든 웹 응용 프로그램을 언로드 할 때, 호출 destroy()의 초기화 서블릿과 필터, 모든 모든 방법을 ServletContext, Servlet, Filter그리고 Listener인스턴스는 휴지통된다. 마지막으로 ServletContextListener#contextDestroyed()호출됩니다.
HttpServletRequest 및 HttpServletResponse
서블릿 컨테이너는 특정 포트 번호에서 HTTP 요청을 수신하는 웹 서버에 연결됩니다 (포트 8080은 일반적으로 개발 중에 사용되고 포트 80은 프로덕션에 사용됨). 클라이언트 (웹 브라우저, 또는으로 예를 들어 사용자의 경우 프로그램 사용이URLConnection ) HTTP 요청을 전송, 서블릿 컨테이너는 새로운 생성 HttpServletRequest과 HttpServletResponse객체와 정의 된 모든 통해 전달 Filter, 결국, 체인 및 Servlet인스턴스를.
의 경우 필터 의 doFilter()메서드가 호출됩니다. 서블릿 컨테이너의 코드가를 호출 chain.doFilter(request, response)하면 요청 및 응답이 다음 필터로 계속 진행되거나 남아있는 필터가없는 경우 서블릿에 도달합니다.
의 경우 서블릿 의 service()메서드가 호출됩니다. 기본적으로이 메소드는의 doXxx()기반으로 호출 할 메소드 중 하나를 결정 request.getMethod()합니다. 결정된 메소드가 서블릿에 없으면 응답에 HTTP 405 오류가 리턴됩니다.
요청 객체는 URL, 헤더, 쿼리 문자열 및 본문과 같은 HTTP 요청에 대한 모든 정보에 대한 액세스를 제공합니다. 응답 객체는 원하는 방식으로 HTTP 응답을 제어하고 보낼 수있는 기능을 제공합니다. 예를 들어 헤더 및 본문 (일반적으로 JSP 파일에서 생성 된 HTML 내용으로)을 설정할 수 있습니다. HTTP 응답이 커밋되고 완료되면 요청 및 응답 개체가 모두 재활용되고 재사용 할 수있게됩니다.
HttpSession
클라이언트가 처음으로 webapp를 방문하거나 HttpSession를 통해 처음으로 얻은 request.getSession()경우, 서블릿 컨테이너는 새 HttpSession객체를 생성하고 길고 고유 한 ID (생성 할 수 있음 session.getId())를 생성하여 서버에 저장합니다. 기억. 서블릿 컨테이너는 또한 설정 Cookie에서 Set-Cookie와 HTTP 응답의 헤더 JSESSIONID의 이름과 그 값과 고유 세션 ID있다.
당으로 HTTP 쿠키 사양 (계약을 준수해야 어떤 점잖은 웹 브라우저와 웹 서버), 클라이언트 (웹 브라우저)는 후속 요청에서이 쿠키 다시 보낼 필요가 Cookie긴 쿠키가 유효한 경우로에 대한 헤더 ( 즉, 고유 ID는 만료되지 않은 세션을 참조해야하며 도메인과 경로는 정확합니다). 브라우저의 내장 HTTP 트래픽 모니터를 사용하여 쿠키가 유효한지 확인할 수 있습니다 (Chrome / Firefox 23 + / IE9 +에서 F12를 누르고 Net / Network 탭을 확인 하십시오). 서블릿 컨테이너는 Cookie들어오는 HTTP 요청 의 헤더에 이름이있는 쿠키 가 있는지 확인하고 JSESSIONID해당 값 (세션 ID)을 사용하여 HttpSession서버 메모리에서 관련 항목을 가져옵니다 .
의 설정에 HttpSession지정된 시간 초과 값을 초과하여 유휴 상태가 될 때까지 (즉, 요청에 사용되지 않음) 유지 <session-timeout>됩니다 web.xml. 시간 종료 값은 기본적으로 30 분입니다. 따라서 클라이언트가 지정된 시간보다 오랫동안 웹 앱을 방문하지 않으면 서블릿 컨테이너가 세션을 휴지통에 버립니다. 쿠키가 지정된 경우에도 이후의 모든 요청은 더 이상 동일한 세션에 액세스 할 수 없습니다. 서블릿 컨테이너는 새 세션을 만듭니다.
클라이언트 측에서 세션 쿠키는 브라우저 인스턴스가 실행되는 동안 활성 상태를 유지합니다. 따라서 클라이언트가 브라우저 인스턴스 (모든 탭 / 창)를 닫으면 세션이 클라이언트 쪽에서 휴지통으로 이동합니다. 새 브라우저 인스턴스에는 세션과 관련된 쿠키가 존재하지 않으므로 더 이상 쿠키가 전송되지 않습니다. 이로 인해 HttpSession완전히 새로운 세션 쿠키가 사용되면서 완전히 새로운 것이 생성됩니다.
간단히 말해서
ServletContext한 웹 응용 프로그램의 삶 등을위한 삶. 모든 세션의 모든 요청 간에 공유 됩니다.
HttpSession클라이언트가 동일한 브라우저 인스턴스를 사용하여 웹 앱과 상호 작용하고 서버 측에서 세션 시간이 초과되지 않는 한 수명이 지속됩니다. 동일한 세션의 모든 요청 간에 공유 됩니다.
HttpServletRequest와 HttpServletResponse서블릿이 클라이언트에서 HTTP 요청을 수신 할 때부터 라이브, 전체 응답 (웹 페이지)에 도착 할 때까지. 그것은되어 있지 다른 곳에서 공유했다.
- 모든
Servlet, Filter그리고 Listener인스턴스는 한 웹 응용 프로그램이 삶으로 살고 있습니다. 그들은 공유됩니다 모두 에서 요청 하는 모든 세션.
- 모든
attribute정의되는 ServletContext, HttpServletRequest그리고 HttpSession질문의 삶에서 대상으로 한 살 것이다. 객체 자체는 JSF, CDI, Spring 등과 같은 Bean 관리 프레임 워크에서 "범위"를 나타냅니다. 이러한 프레임 워크는 범위가 지정된 Bean을 attribute가장 가까운 일치 범위로 저장합니다.
스레드 안전
즉, 주요 관심사는 스레드 안전성 일 수 있습니다. 서블릿과 필터가 모든 요청에서 공유됨을 알아야합니다. Java의 좋은 점은 멀티 스레드이며 다른 스레드 (읽기 : HTTP 요청)가 동일한 인스턴스를 사용할 수 있다는 것입니다. 그렇지 않으면 다시 너무 비싸, 것입니다 init()및 destroy()모든 단일 요청에 대해 그들.
또한 요청 또는 세션 범위 데이터를 서블릿 또는 필터 의 인스턴스 변수 로 지정 해서는 안된다는 것을 알아야합니다 . 다른 세션의 다른 모든 요청과 공유됩니다. 그건 하지 스레드 안전! 아래 예제는 이것을 보여줍니다.
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
또한보십시오: