关于spring:谁再问Servlet的问题我就亲自上门来教学了

1次阅读

共计 2639 个字符,预计需要花费 7 分钟才能阅读完成。

1. 概述

在这篇简短的文章中,咱们将从概念上了解什么是 servletservlet 容器以及它们是如何工作的 **。
同时,还能在申请、响应、会话对象、共享变量和多线程的上下文中看到它们的身影。**

2. Servlets 和 它的容器

servletJEE 用于 web 开发罕用的组件。它们基本上是运行在容器边界内的 Java 程序。总的来说,它们负责承受申请,解决申请,并返回响应

要应用它们,首先须要容器注册 servlet,无论是基于 JEE 还是基于 Spring 的容器,都能够在启动时接管它们。在开始时,容器通过调用 init() 办法来实例化 servlet
初始化实现后,servlet 就能够承受传入的申请。随后,容器将这些申请定向到 servletservice 办法中进行解决。之后,它依据 HTTP 申请类型将申请进一步委托给适当的办法,例如 doGet()doPost()

应用 destroy(),容器会销毁 servlet,并且不再承受传入的申请。咱们将这个 init-service-destroy 的循环称为 servlet 的生命周期。

当初咱们从容器的角度来看,比方 Apache TomcatJetty 在启动时,创立一个 ServletContext 的对象,ServletContext 的工作是充当服务器或容器的内存,并记住与 web 应用程序相关联的所有 servlet、过滤器和侦听器,如其 web.xml 文件或等效注解。在容器进行之前,ServletContext 会始终保留它。

不管怎么说,servletload-on-startup 参数表演重要的角色。如果此参数的值大于零,则只有在启动时服务器才会对其进行初始化。如果未指定此参数,则在申请第一次命中 servlet时调用它的 init()

3. Request, Response 和 Session

在上一节中,咱们探讨了发送申请和接管响应,这基本上是任何 CS 应用程序的根底。当初,咱们从 servlet 的角度来具体理解它们。

在这种状况下,申请将由 HttpServletRequest 示意,响应将用 HttpServletResponse 示意。

每当浏览器或 curl 命令等发送申请时,容器都会创立一个新的 HttpServletRequestHttpServletResponse 对象。而后将这些新对象传递给 servletservice办法。基于 HttpServletRequestmethod 属性,此办法确定应调用哪个 doXXX办法。

除了无关办法的信息外,request 对象还携带其余信息,如头、参数和主体。相似地,HttpServletResponse对象也携带头、参数和主体——咱们能够在 servletdoXXX 办法中设置它们。

这些对象的生命昙花一现。当客户端取得响应时,服务器将标记用于垃圾回收的申请和响应对象。
那么咱们如何在随后的客户端申请或连贯之间放弃一个状态?答案就是 HttpSession

原理是将这些对象绑定到用户会话,以便与特定用户相干的信息能够跨多个申请长久化。这通常是通过应用 cookies 的概念,应用 [JSESSIONID] 作为给定会话的惟一标识符。咱们能够在 web.xml 中指定会话的超时时长。

<session-config>
    <session-timeout>10</session-timeout>
</session-config>

以上配置示意,如果会话闲暇了 10 分钟,服务器将抛弃它。任何后续申请都将创立一个新的会话。

4. Servlets 共享数据

依据所需的范畴,servlet 能够通过多种形式共享数据。

正如在后面的章节中提到的,不同的对象有不同的生命周期。HttpServletRequestHttpServletResponse 对象只存在于一个 servlet 调用之间。HttpSession 只有它处于活动状态并且没有超时,它就会始终存在。

ServletContext的生命周期最长。它与 Web 应用程序一起诞生,只有当应用程序自身敞开时才会被销毁。因为 servlet、filter 和 listener 实例与上下文绑定,所以只有 web 应用程序启动并运行,它们也会始终存在。

因而,如果咱们的需要是在所有 servlet 之间共享数据,假如咱们要计算站点的访问者数量,那么咱们应该将变量放在 ServletContext 中。如果咱们须要在一个会话中共享数据,那么咱们就把它保留在会话范畴内。在本例中,用户名就是一个例子。

最初,还有与单个申请的数据相干的申请范畴,比方申请无效负载。

5. 解决多线程

多个HttpServletRequest 对象彼此共享 servlet,这样每个申请都应用它本人的 servlet 实例线程进行操作。

就线程平安而言,这实际上表明:咱们不应该将申请或会话范畴内的数据指定为 servlet的实例变量。

例如,上面的代码片段:

public class ExampleThree extends HttpServlet {
    
    private String instanceMessage;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {String message = request.getParameter("message");
        instanceMessage = request.getParameter("message");
        request.setAttribute("text", message);
        request.setAttribute("unsafeText", instanceMessage);
        request.getRequestDispatcher("/jsp/ExampleThree.jsp").forward(request, response);
    }
}

在本例中,会话中的所有申请共享 instanceMessage,而 message对于给定的申请对象是惟一的。因而,在并发申请的状况下,instanceMessage 中的数据可能不统一。

6. 总结

在本教程中,咱们探讨了无关 servlet 的一些概念、它们的容器以及它们所围绕的一些根本对象,以及 servlet 如何共享数据和多线程如何影响它们.

如果你感觉文章还不错,记得关注公众号:锅外的大佬
锅外的大佬博客

正文完
 0