Home >Java >javaTutorial >Analysis of Servlet working principle

Analysis of Servlet working principle

巴扎黑
巴扎黑Original
2017-04-30 10:01:161172browse

Web technology has become one of the mainstream Internet Web application technologies today, and Servlet is the core foundation of Java Web technology. Therefore, mastering the working principle of Servlet is a basic requirement for becoming a qualified Java Web technology developer. This article will take you to understand how Java Web technology works based on Servlets. You will know: Take Tomcat as an example to understand how the Servlet container works? How is a web project started in a Servlet container? How does the servlet container parse the servlet you define in web.xml? How are user requests assigned to specified Servlets? How does the Servlet container manage the Servlet life cycle? You will also learn about the class hierarchy of the latest Servlet API, as well as the analysis of some difficult issues in Servlet.

Starting from the Servlet container

To introduce Servlet, we must first explain the Servlet container clearly. The relationship between Servlet and Servlet container is a bit like the relationship between a gun and bullets. The gun is made for bullets, and the bullets make the gun lethal. Although they are interdependent, they develop independently of each other, all of which are the result of adapting to industrial production. From a technical perspective, it is to decouple and collaborate with each other through standardized interfaces. Since interfaces are the key to connecting Servlets and Servlet containers, let's start with their interfaces.

As mentioned earlier, the Servlet container is an independently developed standardized product. There are currently many types of it, but they all have their own market positioning. It is difficult to say who is better and who is worse. Each has its own characteristics. For example, the popular Jetty has made good progress in the field of customization and mobile. Here we will take Tomcat, which is most familiar to everyone, as an example to introduce how the Servlet container manages Servlets. Tomcat itself is also very complex. We will only start with the interface between Servlet and Servlet container. For a detailed introduction to Tomcat, please refer to my other article "Tomcat System Architecture and Pattern Design Analysis".

In Tomcat's container level, the Context container is the wrapper class Wrapper that directly manages the Servlet in the container, so how the Context container runs will directly affect the way the Servlet works.

Figure 1. Tomcat container model

图 1 . Tomcat 容器模型

As can be seen from the above figure, Tomcat's containers are divided into four levels. The container that actually manages Servlets is the Context container. One Context corresponds to a Web project. This can be easily found in the Tomcat configuration file, as follows:

List 1 Context configuration parameters

 <Context path="/projectOne " docBase="D:\projects\projectOne" 
 reloadable="true" />

The following is a detailed introduction to the process of Tomcat parsing the Context container, including how to build a Servlet.

Servlet container startup process

Tomcat7 also began to support embedded functions and added a startup class org.apache.catalina.startup.Tomcat. Tomcat can be easily started by creating an instance object and calling the start method. We can also use this object to add and modify Tomcat's configuration parameters, such as dynamically adding Context, Servlet, etc. Next, we will use this Tomcat class to manage a new Context container. We will select the examples Web project that comes with Tomcat7 and see how it is added to this Context container.

List 2. Add a Web project to Tomcat

 Tomcat tomcat = getTomcatInstance(); 
 File appDir = new File(getBuildDirectory(), "webapps/examples"); 
 tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); 
 tomcat.start(); 
 ByteChunk res = getUrl("http://localhost:" + getPort() + 
               "/examples/servlets/servlet/HelloWorldExample"); 
 assertTrue(res.toString().indexOf("<h1>Hello World!</h1>") > 0);

The code in Listing 1 is to create a Tomcat instance and add a Web application, then start Tomcat and call one of the HelloWorldExample Servlets to see if the expected data is returned correctly.

The code of Tomcat's addWebapp method is as follows:

List 3 .Tomcat.addWebapp

 public Context addWebapp(Host host, String url, String path) { 
        silence(url); 
        Context ctx = new StandardContext(); 
        ctx.setPath( url ); 
        ctx.setDocBase(path); 
        if (defaultRealm == null) { 
            initSimpleAuth(); 
        } 
        ctx.setRealm(defaultRealm); 
        ctx.addLifecycleListener(new DefaultWebXmlListener()); 
        ContextConfig ctxCfg = new ContextConfig(); 
        ctx.addLifecycleListener(ctxCfg); 
        ctxCfg.setDefaultWebXml("org/apache/catalin/startup/NO_DEFAULT_XML"); 
        if (host == null) { 
            getHost().addChild(ctx); 
        } else { 
            host.addChild(ctx); 
        } 
        return ctx; 
 }

We have already introduced that a Web application corresponds to a Context container, which is the Servlet container when the Servlet is running. When adding a Web application, a StandardContext container will be created, and the necessary parameters will be set for the Context container. The url and path represent the application respectively. The two parameters in Tomcat's access path and the actual physical path of this application are consistent with the two parameters in Listing 1. The most important configuration is ContextConfig. This class will be responsible for parsing the entire web application configuration, which will be introduced in detail later. Finally, add this Context container to the parent container Host.

  接下去将会调用 Tomcat 的 start 方法启动 Tomcat,如果你清楚 Tomcat 的系统架构,你会容易理解 Tomcat 的启动逻辑,Tomcat 的启动逻辑是基于观察者模式设计的,所有的容器都会继承 Lifecycle 接口,它管理者容器的整个生命周期,所有容器的的修改和状态的改变都会由它去通知已经注册的观察者(Listener),关于这个设计模式可以参考《 Tomcat 的系统架构与设计模式,第二部分:设计模式》。Tomcat 启动的时序图可以用图 2 表示。

  图 2. Tomcat 主要类的启动时序图(查看大图)

图 2. Tomcat 主要类的启动时序图

  上图描述了 Tomcat 启动过程中,主要类之间的时序关系,下面我们将会重点关注添加 examples 应用所对应的 StandardContext 容器的启动过程。

  当 Context 容器初始化状态设为 init 时,添加在 Contex 容器的 Listener 将会被调用。ContextConfig 继承了 LifecycleListener 接口,它是在调用清单 3 时被加入到 StandardContext 容器中。ContextConfig 类会负责整个 Web 应用的配置文件的解析工作。

  ContextConfig 的 init 方法将会主要完成以下工作:

  1. 创建用于解析 xml 配置文件的 contextDigester 对象


  2. 读取默认 context.xml 配置文件,如果存在解析它


  3. 读取默认 Host 配置文件,如果存在解析它


  4. 读取默认 Context 自身的配置文件,如果存在解析它


  5. 设置 Context 的 DocBase

  ContextConfig 的 init 方法完成后,Context 容器的会执行 startInternal 方法,这个方法启动逻辑比较复杂,主要包括如下几个部分:

  1. 创建读取资源文件的对象


  2. 创建 ClassLoader 对象


  3. 设置应用的工作目录


  4. 启动相关的辅助类如:logger、realm、resources 等


  5. 修改启动状态,通知感兴趣的观察者(Web 应用的配置)


  6. 子容器的初始化


  7. 获取 ServletContext 并设置必要的参数


  8. 初始化“load on startup”的 Servlet

  Web 应用的初始化工作

  Web 应用的初始化工作是在 ContextConfig 的 configureStart 方法中实现的,应用的初始化主要是要解析 web.xml 文件,这个文件描述了一个 Web 应用的关键信息,也是一个 Web 应用的入口。

  Tomcat 首先会找 globalWebXml 这个文件的搜索路径是在 engine 的工作目录下寻找以下两个文件中的任一个 org/apache/catalin/startup/NO_DEFAULT_XML 或 conf/web.xml。接着会找 hostWebXml 这个文件可能会在 System.getProperty("catalina.base")/conf/${EngineName}/${HostName}/web.xml.default,接着寻找应用的配置文件 examples/WEB-INF/web.xml。web.xml 文件中的各个配置项将会被解析成相应的属性保存在 WebXml 对象中。如果当前应用支持 Servlet3.0,解析还将完成额外 9 项工作,这个额外的 9 项工作主要是为 Servlet3.0 新增的特性,包括 jar 包中的 META-INF/web-fragment.xml 的解析以及对 annotations 的支持。

  接下去将会将 WebXml 对象中的属性设置到 Context 容器中,这里包括创建 Servlet 对象、filter、listener 等等。这段代码在 WebXml 的 configureContext 方法中。下面是解析 Servlet 的代码片段:

  清单 4. 创建 Wrapper 实例

 for (ServletDef servlet : servlets.values()) { 
            Wrapper wrapper = context.createWrapper(); 
            String jspFile = servlet.getJspFile(); 
            if (jspFile != null) { 
                wrapper.setJspFile(jspFile); 
            } 
            if (servlet.getLoadOnStartup() != null) { 
                wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue()); 
            } 
            if (servlet.getEnabled() != null) { 
                wrapper.setEnabled(servlet.getEnabled().booleanValue()); 
            } 
            wrapper.setName(servlet.getServletName()); 
            Map<String,String> params = servlet.getParameterMap(); 
            for (Entry<String, String> entry : params.entrySet()) { 
                wrapper.addInitParameter(entry.getKey(), entry.getValue()); 
            } 
            wrapper.setRunAs(servlet.getRunAs()); 
            Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs(); 
            for (SecurityRoleRef roleRef : roleRefs) { 
                wrapper.addSecurityReference( 
                        roleRef.getName(), roleRef.getLink()); 
            } 
            wrapper.setServletClass(servlet.getServletClass()); 
            MultipartDef multipartdef = servlet.getMultipartDef(); 
            if (multipartdef != null) { 
                if (multipartdef.getMaxFileSize() != null && 
                        multipartdef.getMaxRequestSize()!= null && 
                        multipartdef.getFileSizeThreshold() != null) { 
                    wrapper.setMultipartConfigElement(new 
 MultipartConfigElement( 
                            multipartdef.getLocation(), 
                            Long.parseLong(multipartdef.getMaxFileSize()), 
                            Long.parseLong(multipartdef.getMaxRequestSize()), 
                            Integer.parseInt( 
                                    multipartdef.getFileSizeThreshold()))); 
                } else { 
                    wrapper.setMultipartConfigElement(new 
 MultipartConfigElement( 
                            multipartdef.getLocation())); 
                } 
            } 
            if (servlet.getAsyncSupported() != null) { 
                wrapper.setAsyncSupported( 
                        servlet.getAsyncSupported().booleanValue()); 
            } 
            context.addChild(wrapper); 
 }

  这段代码清楚的描述了如何将 Servlet 包装成 Context 容器中的 StandardWrapper,这里有个疑问,为什么要将 Servlet 包装成 StandardWrapper 而不直接是 Servlet 对象。这里 StandardWrapper 是 Tomcat 容器中的一部分,它具有容器的特征,而 Servlet 为了一个独立的 web 开发标准,不应该强耦合在 Tomcat 中。

  除了将 Servlet 包装成 StandardWrapper 并作为子容器添加到 Context 中,其它的所有 web.xml 属性都被解析到 Context 中,所以说 Context 容器才是真正运行 Servlet 的 Servlet 容器。一个 Web 应用对应一个 Context 容器,容器的配置属性由应用的 web.xml 指定,这样我们就能理解 web.xml 到底起到什么作用了。


Create Servlet instance

The parsing work of the Servlet has been completed previously, and it was packaged into a StandardWrapper and added to the Context container, but it still cannot work for us because it has not been instantiated. Below we will introduce how the Servlet object is created and initialized.

​Create Servlet object

If the load-on-startup configuration item of the Servlet is greater than 0, it will be instantiated when the Context container starts. As mentioned earlier, the default globalWebXml will be read when parsing the configuration file, which is in the web.xml file under conf Some default configuration items are defined, which define two Servlets, namely: org.apache.catalina.servlets.DefaultServlet and org.apache.jasper.servlet.JspServlet. Their load-on-startup is 1 and 3 respectively. That is, these two Servlets will be started when Tomcat starts.

The method of creating a Servlet instance starts with Wrapper.loadServlet. What the loadServlet method needs to accomplish is to obtain the servletClass and then pass it to the InstanceManager to create an object based on servletClass.class. If this Servlet is configured with jsp-file, then this servletClass is org.apache.jasper.servlet.JspServlet defined in conf/web.xml.

The relevant class structure diagram for creating a Servlet object is as follows:

Figure 3. Related class structure for creating Servlet object

图 3. 创建 Servlet 对象的相关类结构

Initialize Servlet

Initialize the Servlet in the initServlet method of StandardWrapper. This method is simply to call the init method of the Servlet, and at the same time pass the StandardWrapperFacade that wraps the StandardWrapper object to the Servlet as a ServletConfig. Why the Tomcat container passes StandardWrapperFacade to the Servlet object will be analyzed in detail later.

If the Servlet is associated with a jsp file, then the JspServlet is initialized previously. Next, a simple request will be simulated to call the jsp file in order to compile the jsp file into a class and initialize the class.

In this way, the Servlet object is initialized. In fact, the process from being parsed by the Servlet in web. control and judgment behaviors where some unpredictable errors occur, etc. Here we only focus on some key links to explain, trying to give everyone an overall context.

The following is a complete timing diagram of this process, with some details omitted.

Figure 4. Sequence diagram of initializing Servlet (view larger image)

图 4. 初始化 Servlet 的时序图


Servlet architecture

We know that Java Web applications run based on the Servlet specification, so how does the Servlet itself run? Why design such an architecture.

Figure 5. Servlet top-level class association diagram

图 5.Servlet 顶层类关联图

As can be seen from the above figure, the Servlet specification is based on these classes. There are three classes automatically associated with Servlet, namely ServletConfig, ServletRequest and ServletResponse. These three classes are passed to the Servlet through the container. ServletConfig is passed to the Servlet when the Servlet is initialized, and the last two are passed when the Servlet is called when the request arrives. We clearly understand the significance of ServletRequest and ServletResponse in Servlet operation, but what is the value of ServletConfig and ServletContext to Servlet? A closer look at the methods declared in the ServletConfig interface shows that these methods are all used to obtain some configuration properties of this Servlet, and these configuration properties may be used when the Servlet is running. And what does ServletContext do? The running mode of Servlet is a typical "handshake interactive" running mode. The so-called "handshake type interaction" means that the two modules usually prepare a transaction scenario in order to exchange data, and this scenario follows the transaction process until the transaction is completed. The initialization of this transaction scenario is customized based on the parameters specified by the transaction object. These specified parameters are usually a configuration class. So you are right, the transaction scenario is described by ServletContext, and the customized parameter set is described by ServletConfig. ServletRequest and ServletResponse are the specific objects to be interacted with. They are usually used as transportation tools to deliver interaction results.

ServletConfig is passed from the container during Servlet init, so what exactly is ServletConfig?

The following figure is the class relationship diagram of ServletConfig and ServletContext in the Tomcat container.

 Figure 6. ServletConfig class association diagram in the container

图 6. ServletConfig 在容器中的类关联图

As can be seen from the above figure, both StandardWrapper and StandardWrapperFacade implement the ServletConfig interface, and StandardWrapperFacade is the StandardWrapper facade class. So what is passed to the Servlet is the StandardWrapperFacade object. This class can ensure that the data specified by ServletConfig is obtained from the StandardWrapper without exposing data that ServletConfig does not care about to the Servlet.

Similarly, ServletContext also has a similar structure to ServletConfig. The actual object of ServletContext that can be obtained in Servlet is also an ApplicationContextFacade object. ApplicationContextFacade also ensures that ServletContex can only get the data it should get from the container. They all play a role in encapsulating data, and they all use the facade design pattern.

Through ServletContext, you can get some necessary information in the Context container, such as the working path of the application, the minimum version of Servlet supported by the container, etc.

What are the actual objects of the two ServletRequest and ServletResponse defined in Servlet? , when we create our own Servlet classes, we usually use HttpServletRequest and HttpServletResponse, which inherit ServletRequest and ServletResponse. Why can the ServletRequest and ServletResponse passed by the Context container be converted into HttpServletRequest and HttpServletResponse?

Figure 7.Request related class structure diagram

图 7.Request 相关类结构图

The picture above is the class structure diagram of Request and Response created by Tomcat. Once Tomcat receives a request, it will first create org.apache.coyote.Request and org.apache.coyote.Response. These two classes are used internally by Tomcat to describe a request and corresponding information classes. They are lightweight classes. , their function is to quickly allocate the request to subsequent threads for processing after simple analysis after the server receives the request, so their objects are very small and can be easily recycled by the JVM. Next, when it is handed over to a user thread to handle the request, org.apache.catalina.connector.Request and org.apache.catalina.connector.Response objects are created. These two objects travel through the entire Servlet container until they are passed to the Servlet. What are passed to the Servlet are the facade classes RequestFacade and RequestFacade of Request and Response. The facade mode used here is based on the same purpose as before - to encapsulate the data in the container. . The class transformation of Request and Response corresponding to a request is as shown in the figure below:

Figure 8. The transformation process of Request and Response

图 8.Request 和 Response 的转变过程


How Servlet works

We have already understood how the Servlet is loaded, how the Servlet is initialized, and the architecture of the Servlet. Now the question is how it is called.

When the user initiates a request from the browser to the server, it usually contains the following information: http://hostname: port /contextpath/servletpath. The hostname and port are used to establish a TCP connection with the server, and the following URL is used to select That subcontainer in the server serves the user's request. So how does the server reach the correct Servlet container based on this URL?

This matter is easy to solve in Tomcat7.0, because this kind of mapping work has a special class to complete, this is org.apache.tomcat.util.http.mapper, this class saves all the children in Tomcat's Container container Container information, when the org.apache.catalina.connector. Request class enters the Container container, the mapper will set the host and context containers to the mappingData attribute of the Request based on the hostnane and contextpath of this request. So before the Request enters the Container container, the sub-container it wants to access has already been determined.

Figure 9. Mapper class diagram of Request

图 9.Request 的 Mapper 类关系图

Maybe you have questions, how can there be a complete relationship between containers in mapper? This goes back to the 19-step initialization process of the MapperListener class in Figure 2. The following is the init method code of MapperListener:

List 5. MapperListener.init

 public void init() { 
        findDefaultHost(); 
        Engine engine = (Engine) connector.getService().getContainer(); 
        engine.addContainerListener(this); 
        Container[] conHosts = engine.findChildren(); 
        for (Container conHost : conHosts) { 
            Host host = (Host) conHost; 
            if (!LifecycleState.NEW.equals(host.getState())) { 
                host.addLifecycleListener(this); 
                registerHost(host); 
            } 
        } 
 }

  这段代码的作用就是将 MapperListener 类作为一个监听者加到整个 Container 容器中的每个子容器中,这样只要任何一个容器发生变化,MapperListener 都将会被通知,相应的保存容器关系的 MapperListener 的 mapper 属性也会修改。for 循环中就是将 host 及下面的子容器注册到 mapper 中。

  图 10.Request 在容器中的路由图

图 10.Request 在容器中的路由图

  上图描述了一次 Request 请求是如何达到最终的 Wrapper 容器的,我们现正知道了请求是如何达到正确的 Wrapper 容器,但是请求到达最终的 Servlet 还要完成一些步骤,必须要执行 Filter 链,以及要通知你在 web.xml 中定义的 listener。

  接下去就要执行 Servlet 的 service 方法了,通常情况下,我们自己定义的 servlet 并不是直接去实现 javax.servlet.servlet 接口,而是去继承更简单的 HttpServlet 类或者 GenericServlet 类,我们可以有选择的覆盖相应方法去实现我们要完成的工作。

  Servlet 的确已经能够帮我们完成所有的工作了,但是现在的 web 应用很少有直接将交互全部页面都用 servlet 来实现,而是采用更加高效的 MVC 框架来实现。这些 MVC 框架基本的原理都是将所有的请求都映射到一个 Servlet,然后去实现 service 方法,这个方法也就是 MVC 框架的入口。

  当 Servlet 从 Servlet 容器中移除时,也就表明该 Servlet 的生命周期结束了,这时 Servlet 的 destroy 方法将被调用,做一些扫尾工作。


 Session 与 Cookie

  前面我们已经说明了 Servlet 如何被调用,我们基于 Servlet 来构建应用程序,那么我们能从 Servlet 获得哪些数据信息呢?

  Servlet 能够给我们提供两部分数据,一个是在 Servlet 初始化时调用 init 方法时设置的 ServletConfig,这个类基本上含有了 Servlet 本身和 Servlet 所运行的 Servlet 容器中的基本信息。根据前面的介绍 ServletConfig 的实际对象是 StandardWrapperFacade,到底能获得哪些容器信息可以看看这类提供了哪些接口。还有一部分数据是由 ServletRequest 类提供,它的实际对象是 RequestFacade,从提供的方法中发现主要是描述这次请求的 HTTP 协议的信息。所以要掌握 Servlet 的工作方式必须要很清楚 HTTP 协议,如果你还不清楚赶紧去找一些参考资料。关于这一块还有一个让很多人迷惑的 Session 与 Cookie。

  Session 与 Cookie 不管是对 Java Web 的熟练使用者还是初学者来说都是一个令人头疼的东西。Session 与 Cookie 的作用都是为了保持访问用户与后端服务器的交互状态。它们有各自的优点也有各自的缺陷。然而具有讽刺意味的是它们优点和它们的使用场景又是矛盾的,例如使用 Cookie 来传递信息时,随着 Cookie 个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如 Cookie 占用 200 个字节,如果一天的 PV 有几亿的时候,它要占用多少带宽。所以大访问量的时候希望用 Session,但是 Session 的致命弱点是不容易在多台服务器之间共享,所以这也限制了 Session 的使用。

  不管 Session 和 Cookie 有什么不足,我们还是要用它们。下面详细讲一下,Session 如何基于 Cookie 来工作。实际上有三种方式能可以让 Session 正常工作:

  1. 基于 URL Path Parameter,默认就支持


  2. 基于 Cookie,如果你没有修改 Context 容器个 cookies 标识的话,默认也是支持的


  3. 基于 SSL,默认不支持,只有 connector.getAttribute("SSLEnabled") 为 TRUE 时才支持

  第一种情况下,当浏览器不支持 Cookie 功能时,浏览器会将用户的 SessionCookieName 重写到用户请求的 URL 参数中,它的传递格式如 /path/Servlet;name=value;name2=value2? Name3=value3,其中“Servlet;”后面的 K-V 对就是要传递的 Path Parameters,服务器会从这个 Path Parameters 中拿到用户配置的 SessionCookieName。关于这个 SessionCookieName,如果你在 web.xml 中配置 session-config 配置项的话,其 cookie-config 下的 name 属性就是这个 SessionCookieName 值,如果你没有配置 session-config 配置项,默认的 SessionCookieName 就是大家熟悉的“JSESSIONID”。接着 Request 根据这个 SessionCookieName 到 Parameters 拿到 Session ID 并设置到 request.setRequestedSessionId 中。

Please note that if the client also supports Cookie, Tomcat will still parse the Session ID in the Cookie and overwrite the Session ID in the URL.

If it is the third case, the Session ID will be set according to the javax.servlet.request.ssl_session attribute value.

With the Session ID, the server can create an HttpSession object. The first trigger is through the request. getSession() method. If the current Session ID does not have a corresponding HttpSession object, create a new one and add this object to Saved in the sessions container of org.apache.catalina. Manager, the Manager class will manage the life cycle of all Sessions. Sessions will be recycled when they expire, the server will be shut down, and Sessions will be serialized to disk, etc. As long as this HttpSession object exists, the user can obtain this object based on the Session ID, thus maintaining the state.

 Figure 11.Session related class diagram

图 11.Session 相关类图

As can be seen from the figure above, the HttpSession object obtained from request.getSession is actually the facade object of the StandardSession object. This is the same principle as the previous Request and Servlet. The following figure is the timing diagram of Session work:

Figure 12. Timing diagram of Session work (view large picture)

图 12.Session 工作的时序图

Another point is that the cookies associated with the Session are no different from other Cookies. The configuration of this configuration can be specified through the session-config configuration item in web.xml.


Listener

in Servlet Listener is widely used in the entire Tomcat server. It is designed based on the observer pattern. The design of Listener provides a quick way to develop Servlet applications and can easily control programs and data from another vertical dimension. Currently, Servlet provides 5 observer interfaces for two types of events, which are: 4 EventListeners types, ServletContextAttributeListener, ServletRequestAttributeListener, ServletRequestListener, HttpSessionAttributeListener and 2 LifecycleListeners types, ServletContextListener, HttpSessionListener. As shown below:

 Figure 13. Listener in Servlet (view large image)

图 13.Servlet 中的 Listener

They basically cover every event you are interested in during the entire Servlet life cycle. The implementation classes of these Listeners can be configured in the eae7f28921fa176b20e23abb843be090 tag in web.xml. Of course, Listeners can also be added dynamically in the application. It should be noted that ServletContextListener cannot add new ones after the container is started, because the events it listens to will no longer appear. Mastering the use of these Listeners can make our program design more flexible.


Summarize

This article involves a lot of content. It seems impossible to explain every detail clearly. This article tries to find some key points from the startup of the Servlet container to the initialization of the Servlet, as well as the Servlet architecture. The purpose It allows readers to have an overall and complete structure diagram, and also analyzes some difficult issues in detail. I hope it will be helpful to everyone.

The above is the detailed content of Analysis of Servlet working principle. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn