当前位置: 首页 > 科技观察

谁问Servlet,我就自己教

时间:2023-03-22 01:09:27 科技观察

1.概述在这篇简短的文章中,我们将从概念上了解什么是servlet和servlet容器,以及它们是如何工作的。此外,请在请求、响应、会话对象、共享变量和多线程的上下文中查看它们。2.Servlets及其容器servlets是Web开发常用的JEE组件。它们基本上是在容器边界内运行的Java程序。他们共同负责接受请求、处理请求并返回响应。要使用它们,容器首先需要注册servlet,无论是基于JEE还是基于Spring的容器,都可以在启动时接收它们。一开始,容器通过调用init()方法来实例化servlet。一旦初始化完成,servlet就准备好接受传入的请求。容器然后将这些请求定向到servlet的服务方法进行处理。之后,它进一步将请求委托给适当的方法,例如doGet()或doPost(),具体取决于HTTP请求类型。使用destroy(),容器会销毁servlet,不再接受传入的请求。我们将这个init-service-destroy周期称为servlet生命周期。现在我们从容器的角度来看。例如,当ApacheTomcat或Jetty启动时,它会创建一个ServletContext对象。ServletContext的任务是充当服务器或容器的内存,并记住与Web应用程序关联的所有servlet和过滤器。和侦听器,例如它们的web.xml文件或等效的注释。ServletContext一直存在,直到容器停止。无论如何,servlet的加载启动参数起着重要的作用。如果这个参数的值大于零,它只会在启动时由服务器初始化。如果未指定此参数,则在第一次请求命中时调用servlet的init()。3.请求、响应和会话在上一节中,我们讨论了发送请求和接收响应,它们基本上是任何CS应用程序的基础。现在,让我们从servlet的角度详细了解它们。在这种情况下,请求将由HttpServletRequest表示,响应将由HttpServletResponse表示。每当浏览器或curl命令等发送请求时,容器都会创建一个新的HttpServletRequest和HttpServletResponse对象。然后将这些新对象传递给servlet的服务方法。根据HttpServletRequest的方法属性,该方法确定应调用哪个doXXX方法。除了方法信息外,请求对象还携带其他信息,如头部、参数和主体。类似地,HttpServletResponse对象也带有标头、参数和正文——我们可以在servlet的doXXX方法中设置它们。这些物体的生命是短暂的。当客户端获得响应时,服务器将请求和响应对象标记为垃圾收集。那么我们如何维护后续客户端请求或连接之间的状态呢?答案是HttpSession。这个想法是将这些对象绑定到用户会话,以便与特定用户相关的信息可以跨多个请求持久保存。这通常是通过使用cookie的概念来完成的,使用[JSESSIONID]作为给定会话的唯一标识符。我们可以在web.xml中指定会话超时时间。10上面的配置意思是如果session空闲10分钟,服务器就会丢弃它。任何后续请求都将创建一个新会话。4.Servlet共享数据根据需要的范围,Servlet可以通过多种方式共享数据。正如前面章节所提到的,不同的对象有不同的生命周期。HttpServletRequest和HttpServletResponse对象只存在于一个servlet调用之间。只要HttpSession还活着并且不会超时,它就会一直存在。ServletContext的生命周期最长。它与Web应用程序一起诞生,只有在应用程序本身关闭时才会被销毁。由于servlet、过滤器和侦听器实例绑定到上下文,因此只要Web应用程序启动并运行,它们也会持续存在。因此,如果我们的需求是在所有servlet之间共享数据,比如说我们要统计站点的访问者数量,那么我们应该将变量放在ServletContext中。如果我们需要在会话中共享数据,那么我们将其保存在会话范围内。在这种情况下,用户名就是一个例子。最后,还有与单个请求的数据相关的请求范围,例如请求负载。5.多线程处理多个HttpServletRequest对象相互共享servlet,因此每个请求都使用自己的servlet实例线程进行操作。在线程安全方面,这实际上意味着:我们不应该将请求或会话范围的数据指定为servlet的实例变量。例如,下面的代码片段:publicclassExampleThreeextendsHttpServlet{privateStringinstanceMessage;@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletExceptionmes,IOquestresponse={String.getParameter("message");instanceMessage=request.getParameter("message");request.setAttribute("text",message);request.setAttribute("unsafeText",instanceMessage);request.getRequestDispatcher("/jsp/ExampleThree.jsp").forward(request,response);}}在此示例中,会话中的所有请求共享instanceMessage,并且消息对于给定的请求对象是唯一的。因此,在并发请求的情况下,instanceMessage中的数据可能会不一致。6.总结在本教程中,我们探索了一些关于servlet的概念、它们的容器和它们所包围的一些基本对象,以及servlet如何共享数据以及多线程如何影响它们。圈外人》,可通过以下二维码关注,转载请联系锅外大佬公众号。