Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to call the servlet.service () method

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "how to call the servlet.service () method". In the daily operation, I believe that many people have doubts about how to call the servlet.service () method. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to call the servlet.service () method". Next, please follow the editor to study!

Tomcat is started from org.apache.catalina.startup.Bootstrap#main (). It is roughly divided into three steps, namely init, load and start. The code is as follows:

Java code

Public static void main (String args []) {try {/ / Attempt to load JMX class new ObjectName ("test:foo=bar");} catch (Throwable t) {System.out.println (JMX_ERROR_MESSAGE) Try {/ / Give users some time to read the message before exiting Thread.sleep (5000);} catch (Exception ex) {} return;} if (daemon = = null) {daemon = new Bootstrap () Try {daemon.init (); ★ 1} catch (Throwable t) {t.printStackTrace (); return;}} try {String command = "start" If (args.length > 0) {command = args [args.length-1];} if (command.equals ("startd")) {args [0] = "start"; daemon.load (args); daemon.start () } else if (command.equals ("stopd")) {args [0] = "stop"; daemon.stop ();} else if (command.equals ("start")) {daemon.setAwait (true); daemon.load (args) ★ 2 / / reflection calls Catalina's start method daemon.start (); ★ 3} else if (command.equals ("stop")) {daemon.stopServer (args);}} catch (Throwable t) {t.printStackTrace () }}

From the above, it is clear that tomcat invokes the corresponding command through different parameters.

★ 1 startup, initialization (load class)

Before starting, you need to initialize init (), set the environment and add the package. Here is the init () method. (org.apache.catalina.startup.Bootstrap.init ())

Java code

Public void init () throws Exception {setCatalinaHome (); / / set the Catalina installation directory setCatalinaBase (); / / set the Catalina working directory initClassLoaders (); / / load the jar package / / set classload into the thread so that we can call Thread.currentThread () when we use it. SetContextClassLoader (catalinaLoader); SecurityClassLoad.securityClassLoad (catalinaLoader); / / load the startup class and call its process method if (log.isDebugEnabled ()) log.debug ("Loading startup class"); Class startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina") Object startupInstance = startupClass.newInstance (); / / set the shared expansion class loader if (log.isDebugEnabled ()) log.debug ("Setting startup class properties"); String methodName = "setParentClassLoader"; Class paramTypes [] = new Class [1]; paramTypes [0] = Class.forName ("java.lang.ClassLoader") Object paramValues [] = new Object [1]; paramValues [0] = sharedLoader; Method method = startupInstance.getClass (). GetMethod (methodName, paramTypes); method.invoke (startupInstance, paramValues); catalinaDaemon = startupInstance;}

When loading jar, you need to initialize classloader as follows: (org.apache.catalina.startup.Bootstrap)

Java code

Private void initClassLoaders () {try {commonLoader = createClassLoader ("common", null); catalinaLoader= createClassLoader ("server", commonLoader); sharedLoader = createClassLoader ("shared", commonLoader);} catch (Throwable t) {log.error ("Class loader creation threw exception", t); System.exit (1) }}

The loading method in tomcat is:

| |-commonLoader (common)-> System Loader |

| |-sharedLoader (shared)-> commonLoader-> System Loader |

| |-catalinaLoader (server)-> commonLoader-> System Loader |

Common is a public class loader that is responsible for loading classes that are visible within tomcat and for web applications (jar files under% CATALINA_HOME%/bin/common). Catalina is responsible for loading classes used inside tomcat (jar files under% CATALINA_HOME%/server), which are not visible to web applications. Shared is responsible for loading classes shared between web applications (jar files under% CATALINA_BASE%/shared) that are not visible within tomcat. If the search path for Common is not specified in% CATALINA_HOME%/conf/catalina.Properties, the current class loader, the system class loader, is used as the Common.

★ 2 loads the appropriate resources

The following focuses on the load () method of tomcat. The following figure is a timing diagram of the Catalina.load method.

(1) from the above timing diagram, you can see that the load () method of the Catalina class is called first. The specific code is as follows:

(org.apache.catalina.startup.Catalina).

Java code

Public void load () {initDirs (); / / Before digester-it may be needed initNaming (); / / Create and execute our Digester Digester digester = createStartDigester (); try {inputSource.setByteStream (inputStream); digester.push (this) Digester.parse (inputSource); / / A pair of server.xml parses inputStream.close ();}. / / Start the new server if (server instanceof Lifecycle) {try {server.initialize (); / server initialization work} catch (LifecycleException e) {log.error ("Catalina.start", e);} long T2 = System.currentTimeMillis () Log.info ("Initialization processed in" + (T2-T1) + "ms");}

(2) the initialization of server needs to be carried out in the above load () method. The following figure is the timing diagram of Catalina.initialize, from which you can see the work completed by server initialization.

At this point, the load method is over, the initialization work is over, and let's start with the start method.

★ 3 container startup

When the container starts, Catalina.start () is called, and the following figure shows its timing diagram. You can see from the figure that when the start method of StandardService is called, the start method is called on Container and Connector, respectively.

1. Bootstrap calls the start method of Catalina

Catalina.start () method (org.apache.catalina.startup.Catalina.start ())

Java code

Public void start () {/ / launch server if (server instanceof Lifecycle) {try {((Lifecycle) server). Start ();. }

2. Catalina calls the start method of StandardServer

StandardServer.start () (org.apache.catalina.core.StandardServer.start ())

Java code

Public void start () throws LifecycleException {synchronized (services) {for (int I = 0; I)

< services.length; i++) { if (services[i] instanceof Lifecycle) ((Lifecycle) services[i]).start(); } } 3. StandardServer调用StandardService的start方法 Java代码 org.apache.catalina.core.StandardService.start() ) public void start() throws LifecycleException { if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { // standardEngine的启动 ((Lifecycle) container).start(); } } //两个connector的启动,8080和8009 synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } } 以上StandardService.start()方法主要实现了两个功能,standardEngine的启动和connector的启动,下面分别来介绍。 下面是standardEngine的启动和connector的启动 ● standardEngine的启动 (1) 首先是StandardEngine.start()被调用 Java代码 public void start() throws LifecycleException { // Standard container startup //进行logger,manager,cluster,realm,resource的启动 super.start(); } (2) super.start()--->

Org.apache.catalina.core.ContainerBase#start ()

Java code

Public synchronized void start () throws LifecycleException {/ / (omitted) configuration application component startup / / StandardHost container startup in server.xml, Container children [] = findChildren (); for (int I = 0; I < children.length) If (children [I] instanceof Lifecycle) ((Lifecycle) children [I]) .start ();} / / start of StandardPipeline (pipe between containers) if (pipeline instanceof Lifecycle) ((Lifecycle) pipeline) .start ();}

(3) StandardHost.start () is called

Java code

Public synchronized void start () throws LifecycleException {/ / return to the above containerBase#start to execute pipeline super.start ();}

(4) StandardPipeline#start

Java code

Public synchronized void start () throws LifecycleException {/ / will call the HostConfig#start method lifecycle.fireLifecycleEvent (START_EVENT, null); / / Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent (AFTER_START_EVENT, null);}

(5) HostConfig#start

Java code

Public void start () {/ / summer webapps deployApps ();}

(6) HostConfig#deployApps

Java code

Protected void deployApps () {File appBase = appBase (); File configBase = configBase (); / / Deploy XML descriptors from configBase deployDescriptors (configBase, configBase.list ()); / / Deploy WARs, and loop if additional descriptors are found deployWARs (appBase, appBase.list ()); / / Deploy expanded folders deployDirectories (appBase, appBase.list ()) }

(7) deployWARs

Java code

Protected void deployWARs (File appBase, String [] files) {. DeployWAR (contextPath, dir, file);}

(8) deployWAR

Java code

Protected void deployWAR (String contextPath, File war, String file) {if (context instanceof Lifecycle) {/ / (omitted) Class clazz = Class.forName (host.getConfigClass ()); LifecycleListener listener = (LifecycleListener) clazz.newInstance (); ((Lifecycle) context) .addLifecycleListener (listener) } context.setPath (contextPath); context.setDocBase (file); / / follow the following step, start host.addChild (context) of StandardContext;}

(9) StandardContext#start

During the startup process of Context, the following tasks are mainly completed.

-

A) set the specific directory webappResources of webapp.

B) postWorkDirectory (), create a temporary file directory. There is a work directory under Tomcat to store temporary files.

C) trigger START_EVENT event listener, in which the start () event of ContextConfig is started, and ContextConfig is used to configure web.xml.

D) create a welcome files for context, usually these three startup files: index.html, index.htm, and index.jsp

E) configure filter

F) start the Servlet with.

G) register JMX.

-

At this point, the Container startup is complete, and here is the startup of the connector.

Startup of ● connector

(1) org.apache.catalina.connector.Connector.start ()

Java code

Launch protocolHandler.start of public void start () throws LifecycleException {/ / Http11Protocol ();}

(2) Http11Protocol#start

Java code

Public void start () throws Exception {try {/ / launch endpoint.start () at the end point;} catch (Exception ex) {log.error (sm.getString ("http11protocol.endpoint.starterror"), ex); throw ex;}

(3) JIoEndPoint#start

Java code

Public void start () throws Exception {for (int I = 0; I < acceptorThreadCount; iTunes +) {/ / the acceptor here is a thread with a serversocket startup Thread acceptorThread = new Thread (new Acceptor (), getName () + "- Acceptor-" + I). AcceptorThread.setPriority (threadPriority); acceptorThread.setDaemon (daemon); acceptorThread.start ();}}

(4) Acceptor#run

Java code

Public void run () {/ / Accept the next incoming connection from the server socket try {/ / accept (), wait for the client message, and receive Socket socket = serverSocketFactory.acceptSocket (serverSocket); serverSocketFactory.initSocket (socket) / / Hand this socket off to an appropriate processor if (! processSocket (socket)) {/ / Close socket right away try {socket.close () } catch (IOException e) {/ / Ignore} catch (IOException x) {if (running) log.error (sm.getString ("endpoint.accept.fail") X) } catch (Throwable t) {log.error (sm.getString ("endpoint.accept.fail"), t);}}

At this point, the Connector.start method call is complete. The entire server has been started.

This time, I will explain the process of Tomcat request processing. If there is any inadequacy, please refer to comment.

one。 The overall structure of Tomcat

Tomcat is managed by modularization. The following is the overall structure diagram of Tomcat:

As you can see from the figure above, the core of Tomcat is two components: Connector and Container. Here is an introduction to some concepts.

① Server

A server represents the entire catalina servlet container, and the Server in Tomcat is used to start and listen for server events (such as restart, shutdown, etc.).

② Service

A Service is a combination of one or more Connector and an Engine.

③ Connector

Connector will listen to the customer's request on a specified port, encapsulate the data passed from socket into Request, pass it to Engine for processing, and get the response from Engine and return it to the customer.

Two kinds of Connector are usually used in Tomcat:

A) Http Connector listens for http requests from customer browser at port 8080.

B) AJP Connector listens for servlet/jsp proxy requests from other WebServer (Apache) at port 8009.

II. Analysis of request processing process

1. Connector handles requests

The flow of Connector processing the request is roughly as follows:

When the Connector component starts, it listens for client requests for the relevant port.

(1) accept a new connection request (org.apache.tomcat.util.net.TcpWorkerThread)

Java code

Void runIt (Object [] perThrData) {Socket s = null; try {s = endpoint.acceptSocket (); / / get a request} finally {if (endpoint.isRunning ()) {endpoint.tp.runIt (this) / / start another TcpWorkerTread here to accept other requests. This thread processes accepted requests} TcpConnection con = null; con = (TcpConnection) perThrData [0]; con.setEndpoint (endpoint); con.setSocket (s) Endpoint.getConnectionHandler () .processConnection (con, (Object []) perThrData [1]);}

(2) the newly received request is transmitted to the Http11ConnectionHandler for processing. (org.apache.coyote.http11.Http11Protocol.Http11ConnectionHandler)

Java code

Void processConnection (TcpConnection connection, Object [] thData) {Http11Processor processor=null; processor= (Http11Processor) thdata [Http11Protocol.Thread _ DATA_PROCESSOR]; socket=connection.getSocket (); InputStream in = socket.getInputStream (); OutputStream out = socket.getOutputStream (); processor.setSocket (socket); processor.process (in, out) / / processor is an instance of org.apache.coyote.http11.Http11Processor}

(3) deal with http11 protocol related information in Http11Processor (org.apache.coyote.http11.Http11Processor)

Java code

Void process (InputStream input, OutputStream output) throws IOException {~ slightly ~ inputBuffer.setInputStream (input); outputBuffer.setOutputStream (output); inputBuffer.parseHeaders (); / / http11 protocol header is removed adapter.service (request, response) in this method; / / adapter is an instance of org.apache.catalina.connector.CoyoteAdapter}

The rest of the process is handled by the container.

two。 Container handles request

The container is handled by Pipeline, and some vavle will be placed in this Pipeline, and the request will be passed along the pipeline and processed by vavle. For example, logs, etc., valve can also be customized, you need to check the server.xml configuration file. The related class diagrams are as follows:

The implementations of Engine, Host, Context and Wrapper, the main processing components of Tomcat, all implement the Pipeline interface. The actual processing of requests is that the implementation of Adapter in Adpater,Tomcat is CoyoteAdapter, so the entry of container request processing is the service method of CoyoteAdapter.

1. CoyoteAdapter.service

Assemble the request processing chain

-- StandardEngine. GetPipeline (). GetFirst (). Invoke (request, response)

-- StandardEngineValve.invoke

2. StandardEngineValve.invoke

Host.getPipeline (). GetFirst (). Invoke (request, response)

-- StandardHostValve.invoke

3. StandardHostValve.invoke

-- Context. GetPipeline (). GetFirst (). Invoke (request, response)

-- StandardContextValve.invoke

4. StandardContextValve.invoke

-- ServletRequestListener.requestInitialized

Wrapper.getPipeline (). GetFirst (). Invoke (request, response)

-- StandardWrapperValve.invoke

-- ServletRequestListener.requestDestroyed

5. StandardWrapperValve.invoke

-- assembling Filter+Servlet

-- processing requests

(1) the request from Connector calls the CoyoteAdapter.service () method. (org.apache.catalina.connector.CoyoteAdapter)

Java code

Public void service (org.apache.coyote.Request req, org.apache.coyote.Response res) throws Exception {~ slightly ~ if (request = = null) {request = (Request) connector.createRequest (); request.setCoyoteRequest (req); response = (Response) connector.createResponse (); response.setCoyoteResponse (res) / / create request and response objects ~ ~ slightly ~} try {if (postParseRequest (req, request, res, response)) {connector.getContainer (). GetPipeline (). GetFirst (). Invoke (request, response); / / Container here is StandardEngine object ~ ~ slightly ~}}

(2) the Pipeline of the default StandardEngine will have a StandardEngineValve processing unit (see StandardEngine constructor). (org.apache.catalina.core.StandardEngineValve)

Java code

Public final void invoke (Request request, Response response) throws IOException, ServletException {/ / Select the Host to be used for this Request Host host = request.getHost () If (host = = null) {response.sendError (HttpServletResponse.SC_BAD_REQUEST, sm.getString ("standardEngine.noHost", request.getServerName ()); return } / / Ask this Host to process this request host.getPipeline () .getFirst () .invoke (request, response);}

(3) similarly, the Pipeline of StandardHost will have StandardHostValve processing unit. How StandardHostValve handles requests is similar to StandardEngineValve, and then the request goes to StandardContextValve.invoke

(4) similarly, the Pipeline of StandardContext will have StandardContextValve processing unit.

Java code

Public final void invoke (Request request, Response response) throws IOException, ServletException {/ / Disallow any direct access to resources under WEB-INF or META-INF MessageBytes requestPathMB = request.getRequestPathMB () If ((requestPathMB.startsWithIgnoreCase ("/ META-INF/", 0)) | | (requestPathMB.equalsIgnoreCase ("/ META-INF")) | | (requestPathMB.startsWithIgnoreCase ("/ WEB-INF/", 0)) | (requestPathMB.equalsIgnoreCase ("/ WEB-INF") {String requestURI = request.getDecodedRequestURI () NotFound (requestURI, response); return;} / / Wait if we are reloading while (context.getPaused ()) {try {Thread.sleep (1000) } catch (InterruptedException e) {;}} / / Select the Wrapper to be used for this Request Wrapper wrapper = request.getWrapper (); if (wrapper = = null) {String requestURI = request.getDecodedRequestURI () NotFound (requestURI, response); return;} / / ServletRequestListener. RequestInitialized ~ wrapper.getPipeline (). GetFirst (). Invoke (request, response); / / ServletRequestListener.requestDestroyed ~}

(5) similarly, the StandardWrapper Pipeline will have the StandardWrapperValve processing unit. When the invoke () method calls Filter, the servlet.service () method will also be called.

(org.apache.catalina.core.StandardWrapperValve)

Java code

Void invoke (Request request, Response response, ValveContext valveContext) throws IOException, ServletException {Servlet servlet = null; HttpServletRequest hreq = (HttpServletRequest) request.getRequest (); / / org.apache.catalina.Request is encapsulated into javax.servlet.http.HttpServletRequest. HttpServletResponse hres = (HttpServletResponse) response.getResponse (); / / org.apache.catalina.Response is encapsulated into javax.servlet.http.HttpServletResponse. Servlet = wrapper.allocate (); / / load servlet if ((servlet! = null) & & (filterChain! = null)) {filterChain.doFilter (hreq, hres); / / call the filterchain of this servlet}

(6) call filterchain of servlet to deal with request and response

(org.apache.catalina.core.ApplicationFilterChain)

Java code

Void doFilter (ServletRequest request, ServletResponse response) throws IOException, ServletException {~ slightly ~ ~ internalDoFilter (request,response); ~ ~ slightly ~}

(7) call internalDoFilter () to process the request. (org.apache.catalina.core.ApplicationFilterChain)

Java code

Void internalDoFilter (ServletRequest request, ServletResponse response) throws IOException, ServletException {/ / omit the code handled by filter here, and filter is called one by one. / / if http requests a jsp page, the following servlet will be an instance of org.apache.jasper.servlet.JspServlet class / / if it is a html page, the following servlet will be an instance of org.apache.catalina.servlets.DefaultServlet class if ((request instanceof HttpServletRequest) & & (response instanceof HttpServletResponse)) {servlet.service ((HttpServletRequest) request, (HttpServletResponse) response) Servlet.service (request, response);} else {servlet.service (request, response);}} at this point, the study of "how to call the servlet.service () method" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report