在上一节中,我们看到,一个完整的Web应用程序的开发流程如下:

编写Servlet;

打包为war文件;

复制到Tomcat的webapps目录下;

启动Tomcat。

这个过程是不是很繁琐?如果我们想在IDE中断点调试,还需要打开Tomcat的远程调试端口并且连接上去。

Java的应用程序开发 java应用程序开发过程_java应用程序开发流程

Java的应用程序开发 java应用程序开发过程_服务器_02

许多初学者经常卡在如何在IDE中启动Tomcat并加载webapp,更不要说断点调试了。

我们需要一种简单可靠,能直接在IDE中启动并调试webapp的方法。

因为Tomcat实际上也是一个Java程序,我们看看Tomcat的启动流程:

启动JVM并执行Tomcat的main()方法;

加载war并初始化Servlet;

正常服务。

启动Tomcat无非就是设置好classpath并执行Tomcat某个jar包的main()方法,我们完全可以把Tomcat的jar包全部引入进来,然后自己编写一个main()方法,先启动Tomcat,然后让它加载我们的webapp就行。

我们新建一个web-servlet-embedded工程,编写pom.xml如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.itranswarp.learnjava
web-servlet-embedded
1.0-SNAPSHOT
war
UTF-8
UTF-8
11
11
11
9.0.26
org.apache.tomcat.embed
tomcat-embed-core
${tomcat.version}
provided
org.apache.tomcat.embed
tomcat-embed-jasper
${tomcat.version}
provided
其中,类型仍然为war,引入依赖tomcat-embed-core和tomcat-embed-jasper,引入的Tomcat版本为9.0.26。
不必引入Servlet API,因为引入Tomcat依赖后自动引入了Servlet API。因此,我们可以正常编写Servlet如下:
@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
String name = req.getParameter("name");
if (name == null) {
name = "world";
}
PrintWriter pw = resp.getWriter();
pw.write("
Hello, " + name + "!
"); 
 
pw.flush();
}
}
然后,我们编写一个main()方法,启动Tomcat服务器:
public class Main {
public static void main(String[] args) throws Exception {
// 启动Tomcat:
Tomcat tomcat = new Tomcat();
tomcat.setPort(Integer.getInteger("port", 8080));
tomcat.getConnector();
// 创建webapp:
Context ctx = tomcat.addWebapp("", new File("src/main/webapp").getAbsolutePath());
WebResourceRoot resources = new StandardRoot(ctx);
resources.addPreResources(
new DirResourceSet(resources, "/WEB-INF/classes", new File("target/classes").getAbsolutePath(), "/"));
ctx.setResources(resources);
tomcat.start();
tomcat.getServer().await();
}
}

这样,我们直接运行main()方法,即可启动嵌入式Tomcat服务器,然后,通过预设的tomcat.addWebapp("", new File("src/main/webapp"),Tomcat会自动加载当前工程作为根webapp,可直接在浏览器访问http://localhost:8080/:

Java的应用程序开发 java应用程序开发过程_加载_03

通过main()方法启动Tomcat服务器并加载我们自己的webapp有如下好处:

启动简单,无需下载Tomcat或安装任何IDE插件;

调试方便,可在IDE中使用断点调试;

使用Maven创建war包后,也可以正常部署到独立的Tomcat服务器中。

对SpringBoot有所了解的童鞋可能知道,SpringBoot也支持在main()方法中一行代码直接启动Tomcat,并且还能方便地更换成Jetty等其他服务器。它的启动方式和我们介绍的是基本一样的,后续涉及到SpringBoot的部分我们还会详细讲解。

练习

小结

开发Servlet时,推荐使用main()方法启动嵌入式Tomcat服务器并加载当前工程的webapp,便于开发调试,且不影响打包部署,能极大地提升开发效率。