Servlet

0x01 Servlet First Shoot

  1. 引入依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina</artifactId>
    <version>9.0.60</version>
</dependency>
  1. 自定义Servlet

package servlets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init....");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("Hello Servlet");
    }
}
  1. 注册Servlet(web.xml)

访问/test 返回页面Hello Servlet

0x02 Create Servlet Memory Shell

init处下断点,观察调用栈

org.apache.catalina.core.StandardContext#startInternal

image-20230201130317778

findChildren()把所有Wrapper传入loadOnStartup进行处理

org.apache.catalina.core.StandardContext#loadOnStartup

讲Tomcat架构的时候提到,一个 Wrapper 对应一个 Servlet。负责管理 Servlet ,包括 Servlet 的装载、初始化、执行以及资源回收。

这里的wrapper.load()应该就对应着Servlet的装载

每个Servlet的启动顺序在web.xml中,如果没有声明 load-on-startup 属性(默认为-1),则该Servlet会被动态添加到容器。

wrapper.load() => loadServlet

image-20230201132848862

可以看到这里是通过获取servletClass来装载Servlet

完成装载后,进行初始化,根据请求进行调用,最终销毁

装载:启动服务器时加载Servlet的实例

初始化:web服务器启动时或web服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作由init()方法负责执行完成

调用:即每次调用Servlet的service(),从第一次到以后的多次访问,都是只是调用doGet()或doPost()方法

销毁:停止服务器时调用destroy()方法,销毁实例

WrapperfindChildren()遍历的来的,去看看findChildren()所在类有无addChild()之类的用于添加Wrapper的方法

org.apache.catalina.core.ContainerBase#addChild

image-20230201133218963

实际上StandardContext重写了父类ContainerBaseaddChild方法

image-20230201133404583

先调用父类的addChild,接着进行访问jsp的处理

0x03 POC

Last updated

Was this helpful?