栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

servlet如何工作?实例化,会话,共享变量和多线程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

servlet如何工作?实例化,会话,共享变量和多线程

ServletContext

当servlet容器(例如ApacheTomcat)启动时,它将部署并加载所有Web应用程序。加载Web应用程序后,Servlet容器将创建ServletContext一次并将其保存在服务器的内存中。Web应用程序的web.xml所有包含的

web-fragment.xml
文件进行解析,每个
<servlet>
<filter>
<listener>
发现(或每一类注释用@WebServlet,@WebFilter并@WebListener分别)被实例化一次,并保存在服务器的内存。对于每个实例化的过滤器,其init()方法均通过new调用FilterConfig。

当a的

Servleta<servlet>``<load-on-startup>
@WebServlet(loadOnStartup)value
大于时0,则init()在启动期间还会使用new调用其方法ServletConfig。这些servlet以该值指定的相同顺序进行初始化(1为1st,2为2nd等)。如果多于一个的servlet指定了相同的值,则每个这些小服务程序的如它们出现在加载以相同的顺序web.xml,
web-fragment.xml
或@WebServlet类加载。如果不存在“启动时加载”值,则init()当HTTP请求首次访问该servlet时,将调用该方法。

当Servlet容器完成上述所有初始化步骤后,

ServletContextListener#contextInitialized()
将调用。

当servlet容器关闭时,它卸载所有Web应用程序,调用destroy()其全部初始化servlet和过滤器,所有的方法ServletContext,Servlet,Filter和Listener实例丢弃。最后,

ServletContextListener#contextDestroyed()
将被调用。

HttpServletRequest和HttpServletResponse

Servlet容器连接到Web服务器,该Web服务器在某个端口号上侦听HTTP请求(端口8080通常在开发过程中使用,而端口80在生产中使用)。当客户端(例如,使用Web浏览器或以编程方式使用的用户URLConnection)发送HTTP请求时,Servlet容器将创建newHttpServletRequest和HttpServletResponse对象,并将它们通过Filter链中定义的任何对象(最后是Servlet实例)传递。

对于filter,将doFilter()调用该方法。当servlet容器的代码调用时

chain.doFilter(request, response)
,请求和响应将继续到下一个过滤器,如果没有剩余的过滤器,则单击servlet。

对于servlet,将service()调用该方法。默认情况下,此方法根据来确定doXxx()要调用的方法之一

request.getMethod()
。如果servlet中没有确定的方法,则在响应中返回HTTP 405错误。

request对象提供对有关HTTP请求的所有信息的访问,例如URL,标头,查询字符串和正文。响应对象提供了以所需方式控制和发送HTTP响应的功能,例如,允许您设置标头和正文(通常使用从JSP文件生成的HTML内容)。提交并完成HTTP响应后,请求和响应对象都将被回收并可供重用。

HttpSession

当客户端首次访问该Web应用程序和/或通过首次访问该应用程序

HttpSession
request.getSession()
Servlet
容器将创建一个新HttpSession对象,生成一个长而唯一的ID(您可以通过获取
session.getId()
),并将其存储在服务器的记忆。Servlet容器还在HTTP响应cookie的Set-cookie标头中设置aJSESSIONID作为其名称,并将唯一会话ID作为其值。

根据HTTP cookie规范(任何体面的Web浏览器和Web服务器都必须遵守的合同),cookie只要cookie有效,客户端(Web浏览器)就需要在标头的后续请求中将该cookie发送回去(也就是说,唯一ID必须指向未过期的会话,并且域和路径正确。使用浏览器的内置HTTP流量监视器,您可以验证cookie是否有效(在Chrome / Firefox 23 + / IE9 +中按F12,然后检查“网络/网络”标签)。Servlet容器将检查cookie每个传入HTTP请求的标头中是否存在具有该名称的cookie,JSESSIONID并使用其值(会话ID)HttpSession从服务器的内存中获取关联。

HttpSession活,直到它停留已经空闲(即,在请求未使用)超过规定的超时值

<session-timeout>
,在设定web.xml。超时值默认为30分钟。因此,当客户端访问Web应用程序的时间不超过指定的时间时,Servlet容器将破坏会话。每个后续请求,即使指定了cookie,也将无法再访问同一会话;servlet容器将创建一个新会话。

在客户端,只要浏览器实例正在运行,会话cookie就会保持活动状态。因此,如果客户端关闭浏览器实例(所有选项卡/窗口),则会话将被丢弃在客户端侧。在新的浏览器实例中,与会话关联的cookie将不存在,因此将不再发送。这将导致HttpSession创建一个全新的会话,并使用一个全新的会话cookie。

简而言之

  • ServletContext
    生活,只要Web应用程序的生命。它在所有会话的所有请求之间共享。
    HttpSession
    生活,只要客户端与同一个浏览器实例中的Web应用程序进行交互,和会话未在服务器端超时。它在同一会话中的所有请求之间共享。
  • HttpServletRequest
    HttpServletResponse
    现场从servlet接收来自客户端的HTTP请求的时间,直到完全缓解(网页)已经到来。它没有在其他地方共享。
  • 只要Web应用程序存在
    Servlet
    ,所有
    Filter
    Listener
    实例都会存在。它们在所有会话的所有请求之间共享。
  • 任何attribute被定义
    ServletContext
    HttpServletRequest
    并且
    HttpSession
    只要将生活中的问题生活中的对象。对象本身代表了诸如JSF,CDI,Spring等之类的bean管理框架中的“作用域”。这些框架将其范围内的bean作为attribute其最接近的匹配范围存储。
    线程安全
    也就是说,您最关心的可能是线程安全。现在,您应该知道所有请求之间都共享servlet和过滤器。这对Java来说是一件好事,它是多线程的,并且不同的线程(阅读:HTTP请求)可以使用同一实例。否则,重新创建init()以及destroy()针对每个单个请求的重新创建都将过于昂贵。

您还应该意识到,永远不要将任何请求或会话范围的数据分配为Servlet或过滤器的实例变量。它将在其他会话中的所有其他请求之间共享。那不是线程安全的!下面的示例说明了这一点:

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.    } }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/569754.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号