1. 引言

大家如果使用过SpringBoot都知道springBoot是内嵌了web容器的, 只需要我们调用SpringBootApplication.run()就可以启动web容器

2. 实现内嵌tomcat的启动

  • pom
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-el</artifactId>
            <version>8.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>8.5.5</version>
        </dependency>
    </dependencies>
  • 启动类
    注意webappDirLocation如果是多个模块儿会存在问题,默认找的父工程

addContext方法和addWebApp方法; 其中addWebapp方法是需要依赖japarser依赖用于解析jsp; 而addContext方法不会依赖; 但是不适用addWebapp程序就不认为当前tomcat是一个web项目也就不会加载ServletContainerInitializer

public class Main {
 
    public static void main(String[] args) throws Exception {
        //工作目录
        String webappDirLocation = "src/main/webapp/";
        Tomcat tomcat = new Tomcat();
 
        //The port that we should run on can be set into an environment variable
        //Look for that variable and default to 8080 if it isn't there.
        String webPort = System.getenv("PORT");
        if(webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
 
        tomcat.setPort(Integer.valueOf(webPort));
        //此处还有一个addContext方法
        tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
        System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath());
 
        tomcat.start();
        tomcat.getServer().await();
    }
}

3.实现静态资源访问

前端可以直接访问后端classpath下的内容这是如何做到的, 实际上是用过servlet来实现的,直接利用response向页面输出流

  • 静态资源处理Servlet实现
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String path = HelloServlet.class.getResource("/").getPath();
        String requestURI = req.getRequestURI();
        String file = path + requestURI;
        //IO.....
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  • 添加处理静态资源Servlet

此处利用了tomcat启动时的加载机制实现

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {
        ServletRegistration.Dynamic registration = servletCxt.addServlet("hgy", new HelloServlet());
        registration.addMapping("/");
    }
}

总结

以上首先实现了tomcat的内嵌启动方式,这就实现了tomcat的启动,在启动的时候又动态的添加了Servlet这样就能够使用浏览器访问classpath下面的静态资源时能够被访问到

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐