서블릿은 어떻게 작동합니까? 인스턴스화, 세션, 공유 변수 및 멀티 스레딩
수많은 서블릿을 보유한 웹 서버가 있다고 가정 해 보겠습니다. 이러한 서블릿간에 전달되는 정보를 위해 세션 및 인스턴스 변수를 설정합니다.
이제 두 명 이상의 사용자가이 서버에 요청을 보내면 세션 변수는 어떻게됩니까? 그들은 모든 사용자에게 공통적일까요 아니면 각 사용자마다 다를까요? 만약 그들이 다르다면 서버는 다른 사용자를 어떻게 구별 할 수 있었습니까?
한 가지 더 유사한 질문, n
특정 서블릿에 액세스하는 사용자가있는 경우이 서블릿은 첫 번째 사용자가 처음 액세스 할 때만 인스턴스화되거나 모든 사용자에 대해 개별적으로 인스턴스화됩니까? 즉, 인스턴스 변수는 어떻게됩니까?
ServletContext
서블릿 컨테이너 (예 : Apache Tomcat )가 시작되면 모든 웹 애플리케이션을 배포하고로드합니다. 웹 애플리케이션이로드되면 서블릿 컨테이너는 ServletContext
한 번만 생성 하여 서버의 메모리에 보관합니다. 웹 앱 web.xml
및 포함 된 모든 web-fragment.xml
파일이 구문 분석되고 각 <servlet>
, <filter>
및 <listener>
found (또는 각각 @WebServlet
, @WebFilter
및 주석이 추가 된 각 클래스 @WebListener
)가 한 번 인스턴스화되고 서버의 메모리에도 유지됩니다. 인스턴스화 된 각 필터에 대해 해당 init()
메서드는 새로운 FilterConfig
.
A는 때 Servlet
가 <servlet><load-on-startup>
나 @WebServlet(loadOnStartup)
보다 더 가치 이상을 0
, 다음의 init()
방법은 새로운으로 시작하는 동안 호출됩니다 ServletConfig
. 해당 서블릿은 해당 값 ( 1
1st, 2
2nd 등)에 지정된 것과 동일한 순서로 초기화됩니다 . 동일한 값 이상의 서블릿 지정되면 그들은에 나타나는 경우, 그 다른 서블릿 각각 동일한 순서로 로딩 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 요청에 대한 모든 정보에 대한 액세스를 제공합니다. 응답 객체는 예를 들어 헤더와 본문 (일반적으로 JSP 파일에서 생성 된 HTML 콘텐츠 사용)을 설정할 수 있도록하여 원하는 방식으로 HTTP 응답을 제어하고 보내는 기능을 제공합니다. HTTP 응답이 커밋되고 완료되면 요청 및 응답 개체가 모두 재활용되고 다시 사용할 수 있습니다.
HttpSession
클라이언트가 처음으로 webapp을 방문하거나 HttpSession
를 통해 처음으로를 가져 오면 request.getSession()
서블릿 컨테이너는 새 HttpSession
객체를 만들고 길고 고유 한 ID (를 통해 얻을 수 있음 session.getId()
)를 생성 한 다음 서버의 기억. 서블릿 컨테이너는 또한 HTTP 응답 Cookie
의 Set-Cookie
헤더에 a 를 JSESSIONID
이름으로 설정하고 고유 한 세션 ID를 값으로 설정합니다.
당으로 HTTP 쿠키 사양 (계약을 준수해야 어떤 점잖은 웹 브라우저와 웹 서버), 클라이언트 (웹 브라우저)는 후속 요청에서이 쿠키 다시 보낼 필요가 Cookie
긴 쿠키가 유효한 경우로에 대한 헤더 ( 즉, 고유 ID는 만료되지 않은 세션을 참조해야하며 도메인 및 경로가 정확해야합니다. 브라우저에 내장 된 HTTP 트래픽 모니터를 사용하여 쿠키가 유효한지 확인할 수 있습니다 (Chrome / Firefox 23 + / IE9 +에서 F12를 누르고 Net / Network 탭 확인). 서블릿 컨테이너는 Cookie
들어오는 모든 HTTP 요청 의 헤더에서 이름이있는 쿠키 가 있는지 확인하고 JSESSIONID
해당 값 (세션 ID)을 사용하여 HttpSession
서버의 메모리에서 관련 정보를 가져옵니다 .
의 설정 인에 HttpSession
지정된 시간 초과 값 이상 동안 유휴 상태 (즉, 요청에 사용되지 않음)가 될 때까지 활성 상태를 유지합니다 . 제한 시간 값의 기본값은 30 분입니다. 따라서 클라이언트가 지정된 시간보다 오랫동안 웹 앱을 방문하지 않으면 서블릿 컨테이너가 세션을 폐기합니다. 쿠키가 지정된 경우에도 모든 후속 요청은 더 이상 동일한 세션에 액세스 할 수 없습니다. 서블릿 컨테이너는 새 세션을 생성합니다.<session-timeout>
web.xml
클라이언트 측에서 세션 쿠키는 브라우저 인스턴스가 실행되는 동안 활성 상태를 유지합니다. 따라서 클라이언트가 브라우저 인스턴스 (모든 탭 / 창)를 닫으면 세션이 클라이언트 측에서 삭제됩니다. 새 브라우저 인스턴스에서는 세션과 관련된 쿠키가 존재하지 않으므로 더 이상 전송되지 않습니다. 이로 인해 HttpSession
완전히 새로운 세션 쿠키가 사용되는 완전히 새로운 것이 생성됩니다.
간단히 말해서
ServletContext
한 웹 응용 프로그램의 삶 등을위한 삶. 모든 세션의 모든 요청 간에 공유 됩니다.HttpSession
긴 클라이언트가 동일한 브라우저 인스턴스 웹 응용 프로그램과 상호 작용하고, 세션이 서버 측에서 제한 시간을 초과하지 않은만큼을위한 삶. 동일한 세션의 모든 요청 간에 공유 됩니다.HttpServletRequest
와HttpServletResponse
서블릿이 클라이언트에서 HTTP 요청을 수신 할 때부터 라이브, 전체 응답 (웹 페이지)에 도착 할 때까지. 그것은되어 있지 다른 곳에서 공유했다.- 모든
Servlet
,Filter
그리고Listener
인스턴스는 한 웹 응용 프로그램이 삶으로 살고 있습니다. 모든 세션의 모든 요청 간에 공유 됩니다. - 모든
attribute
정의되는ServletContext
,HttpServletRequest
그리고HttpSession
질문의 삶에서 대상으로 한 살 것이다. 객체 자체는 JSF, CDI, Spring 등과 같은 빈 관리 프레임 워크에서 "범위"를 나타냅니다. 이러한 프레임 워크는 범위가 지정된 빈을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.
}
}
또한보십시오:
- JSF, Servlet 및 JSP의 차이점은 무엇입니까?
- Java에서 세션 관리를위한 최상의 옵션
- 서블릿 매핑 URL 패턴에서 /와 / *의 차이점
- 서블릿의 doGet 및 doPost
- 서블릿이 여러 동시 브라우저 요청을 동시에 처리하는 것 같습니다.
- 서블릿이 스레드로부터 안전하지 않은 이유는 무엇입니까?
세션
In short: the web server issues a unique identifier to each visitor on his first visit. The visitor must bring back that ID for him to be recognised next time around. This identifier also allows the server to properly segregate objects owned by one session against that of another.
Servlet Instantiation
If load-on-startup is false:
If load-on-startup is true:
Once he's on the service mode and on the groove, the same servlet will work on the requests from all other clients.
Why isn't it a good idea to have one instance per client? Think about this: Will you hire one pizza guy for every order that came? Do that and you'd be out of business in no time.
It comes with a small risk though. Remember: this single guy holds all the order information in his pocket: so if you're not cautious about thread safety on servlets, he may end up giving the wrong order to a certain client.
Session in Java servlets is the same as session in other languages such as PHP. It is unique to the user. The server can keep track of it in different ways such as cookies, url rewriting etc. This Java doc article explains it in the context of Java servlets and indicates that exactly how session is maintained is an implementation detail left to the designers of the server. The specification only stipulates that it must be maintained as unique to a user across multiple connections to the server. Check out this article from Oracle for more information about both of your questions.
Edit There is an excellent tutorial here on how to work with session inside of servlets. And here is a chapter from Sun about Java Servlets, what they are and how to use them. Between those two articles, you should be able to answer all of your questions.
When the servlet container (like Apache Tomcat) starts up, it will read from the web.xml file (only one per application) if anything goes wrong or shows up an error at container side console, otherwise, it will deploy and load all web applications by using web.xml (so named it as deployment descriptor).
During instantiation phase of the servlet, servlet instance is ready but it cannot serve the client request because it is missing with two pieces of information:
1: context information
2: initial configuration information
Servlet engine creates servletConfig interface object encapsulating the above missing information into it servlet engine calls init() of the servlet by supplying servletConfig object references as an argument. Once init() is completely executed servlet is ready to serve the client request.
Q) In the lifetime of servlet how many times instantiation and initialization happens ??
A)only once (for every client request a new thread is created) only one instance of the servlet serves any number of the client request ie, after serving one client request server does not die. It waits for other client requests ie what CGI (for every client request a new process is created) limitation is overcome with the servlet (internally servlet engine creates the thread).
Q)How session concept works?
A)whenever getSession() is called on HttpServletRequest object
Step 1: request object is evaluated for incoming session ID.
Step 2: if ID not available a brand new HttpSession object is created and its corresponding session ID is generated (ie of HashTable) session ID is stored into httpservlet response object and the reference of HttpSession object is returned to the servlet (doGet/doPost).
Step 3: if ID available brand new session object is not created session ID is picked up from the request object search is made in the collection of sessions by using session ID as the key.
Once the search is successful session ID is stored into HttpServletResponse and the existing session object references are returned to the doGet() or doPost() of UserDefineservlet.
Note:
1)when control leaves from servlet code to client don't forget that session object is being held by servlet container ie, the servlet engine
2)multithreading is left to servlet developers people for implementing ie., handle the multiple requests of client nothing to bother about multithread code
Inshort form:
A servlet is created when the application starts (it is deployed on the servlet container) or when it is first accessed (depending on the load-on-startup setting) when the servlet is instantiated, the init() method of the servlet is called then the servlet (its one and only instance) handles all requests (its service() method being called by multiple threads). That's why it is not advisable to have any synchronization in it, and you should avoid instance variables of the servlet when the application is undeployed (the servlet container stops), the destroy() method is called.
Sessions - what Chris Thompson said.
Instantiation - a servlet is instantiated when the container receives the first request mapped to the servlet (unless the servlet is configured to load on startup with the <load-on-startup>
element in web.xml
). The same instance is used to serve subsequent requests.
The Servlet Specification JSR-315 clearly defines the web container behavior in the service (and doGet, doPost, doPut etc.) methods (2.3.3.1 Multithreading Issues, Page 9):
A servlet container may send concurrent requests through the service method of the servlet. To handle the requests, the Servlet Developer must make adequate provisions for concurrent processing with multiple threads in the service method.
Although it is not recommended, an alternative for the Developer is to implement the SingleThreadModel interface which requires the container to guarantee that there is only one request thread at a time in the service method. A servlet container may satisfy this requirement by serializing requests on a servlet, or by maintaining a pool of servlet instances. If the servlet is part of a Web application that has been marked as distributable, the container may maintain a pool of servlet instances in each JVM that the application is distributed across.
For servlets not implementing the SingleThreadModel interface, if the service method (or methods such as doGet or doPost which are dispatched to the service method of the HttpServlet abstract class) has been defined with the synchronized keyword, the servlet container cannot use the instance pool approach, but must serialize requests through it. It is strongly recommended that Developers not synchronize the service method (or methods dispatched to it) in these circumstances because of detrimental effects on performance
As is clear from above explanations, by implementing the SingleThreadModel, a servlet can be assured thread-safety by the servlet container. The container implementation can do this in 2 ways:
1) Serializing requests (queuing) to a single instance - this is similar to a servlet NOT implementing SingleThreadModel BUT synchronizing the service/ doXXX methods; OR
2) Creating a pool of instances - which's a better option and a trade-off between the boot-up/initialization effort/time of the servlet as against the restrictive parameters (memory/ CPU time) of the environment hosting the servlet.
No. Servlets are not Thread safe
This is allows accessing more than one threads at a time
if u want to make it Servlet as Thread safe ., U can go for
Implement SingleThreadInterface(i)
which is a blank Interface there is no
methods
or we can go for synchronize methods
we can make whole service method as synchronized by using synchronized
keyword in front of method
Example::
public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOException
or we can the put block of the code in the Synchronized block
Example::
Synchronized(Object)
{
----Instructions-----
}
전체 방법을 만드는 것보다 Synchronized 블록이 낫다고 느낍니다
동기화 됨
'development' 카테고리의 다른 글
Node.js의 Express.js에서 GET (쿼리 문자열) 변수를 얻는 방법은 무엇입니까? (0) | 2020.09.27 |
---|---|
git : 새 파일을 포함하여 모든 작업 디렉토리 변경을 취소합니다. (0) | 2020.09.27 |
문자열에서 공백을 어떻게 제거합니까? (0) | 2020.09.27 |
스크롤 후 요소가 보이는지 확인하는 방법은 무엇입니까? (0) | 2020.09.27 |
Twitter Bootstrap 3을 사용하여 열 중앙에 배치 (0) | 2020.09.27 |