1.两种类型tomcat
- 传统tomcat:需要jar部署,通过BootStrap启动
- 嵌入式tomcat:maven引入Tomcat类,自定义启动插件(Connector,Engin,Host,Context,Wrapper)
- 能搞嵌入式的根本原因:开源
- 如SpringBoor使用的就是嵌入式Tomcat
- Tomcat类中有默认TomcatRunner插件,可以启动;但仍然可以自定义tomcat插件,来做自定义启动
2.手写传统tomcat
具体请参考:【Tomcat】第八篇:基于BIO的150代码手写Tomcat(超详细注释)
3.手写嵌入式tomcat插件
下面先贴一张项目结构的截图:
3.1 在 pom.xml 引入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 引入Tomcat类 -->
<dependency>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
3.2 准备 Servlet 示例
先写一个处理业务逻辑的Servlet示例,在下面插件配置时要用
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("hello world!!!");
// String message = request.getParameter("message");
// response.getWriter().print(message);
}
}
3.3 编写插件:EmbeddedTomcat(核心)
这里先强调一下,插件的目的是为了对现有资源灵活运用,它既可以大到几十兆的压缩包,也可以小到只有一个类。就比如这里的嵌入式tomcat插件,它只用下面的 EmbeddedTomcat 这一个类就可以实现对引入的 Tomcat 包相关资源的灵活管控 。
EmbeddedTomcat 这个类主要有两个作用:
- 实现自定义配置和启动。即传统tomcat的server.xml 和 web.xml 的相关配置都在这里。
- 是启动 Tocmat 的入口。
public class EmbeddedTomcatServer {
public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
// 1.设置Connctor,包括端口
Connector connector = tomcat.getConnector();
connector.setPort(8080);
// 2.设置Engine,此处没什么可以设的...
// 3.设置Host,包括域名,context路径 ---> 至此Tomcat可以正常启动,只不过没有
Host host = tomcat.getHost();
host.setAppBase("webapp");
host.setName("localhost");
// 4.设置Context,包括host与应用的位置
String classpath = System.getProperty("user.dir"); // C:\Users\13275\Documents\Java\...
Context context = tomcat.addContext(host, "/", classpath);
if (context instanceof StandardContext) {
// Context还可以设置默认web.xml
// StandardContext ctx = (StandardContext)context;
// ctx.setDefaultContextXml("C:\\Users\\...\\web.xml");
// 5.设置Wrapper(Servlet),及其映射路径(注:servlet中的@webServlet没用)
Wrapper servlet = tomcat.addServlet("/", "DemoServlet", new DemoServlet());
servlet.addMapping("/demo");
}
// 启动tomcat
tomcat.start();
// 防止main提前结束,使main阻塞
tomcat.getServer().await();
}
}
成果演示
启动EmbeddedTomcat的main函数,然后在浏览器输入localhost:8080/demo,可以看到正确输出。