Tomcat基础知识
Tomcat简介
Tomcat 是一个小型的轻量级应用服务器,其主要作用为Servlet和 JSP容器,支持全部JSP以及Servlet规范。但它同样具有处理HTML页面的功能,可以充当Web服务器。简单点说,Tomcat可以看成是Web服务器+Servlet容器,不过其作为Web服务器功能较弱。
Tomcat架构
Tomcat大体上可以看成由 Connector 和 Container 组件组成。Connector组件负责在服务器端处理客户端连接(客户端连接、接收客户端消息报文、消息报文的解析等),Container负责对客户端的请求进行逻辑处理,并把结果返回给客户端。
Container包含了Engine、Host、Context、Wapper,它们不是平行关系,而是父子关系。
- Engine:表示整个Catalina的Servlet的引擎,一个Service只能包含一个Engine
- Host:代表一个虚拟主机或者一个站点,可以个给Tomcat配置多个虚拟主机
- Context:代表一个web应用,一个应用可以有多个Context
- Wapper: 代表一个Servlet
JavaWeb三大组件
Servlet
Servlet用来处理请求和发送响应,其是为了解决实现动态页面而衍生的东西。
Servlet的生命周期
Servlet的生命周期分为如下五部分:
- 加载:当Tomcat第一次访问Servlet的时候,Tomcat会负责创建Servlet的实例
- 初始化:当Servlet被实例化后,Tomcat会调用
init()
方法初始化这个对象 - 处理服务:当浏览器访问Servlet的时候,Servlet 会调用
service()
方法处理请求 - 销毁:当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用
destroy()
方法,让该实例释放掉所占的资源。一个Servlet如果长时间不被使用的话,也会被Tomcat自动销毁 - 卸载:当Servlet调用完
destroy()
方法后,等待垃圾回收。如果有需要再次使用这个Servlet,会重新调用init()
方法进行初始化操作
Servlet简单使用
接下来我们编写一个简单的Servlet
Servlet需要继承Servlet接口并实现以下五个方法
显然这样过于麻烦,我们可以使用封装好了的两个类,分别是GenericServlet
类和HttpServlet
类
GenericServlet类继承了Servlet接口,且帮我们实现了除service()的其他四个方法,大大节约了开发时间。
而HttpServlet是GenericServlet的子类,其在GenericServlet的基础上专门针对HTTP协议进行了处理,有一些针对HTTP请求的处理方法,例如doGet、doPost等。
我们这里使用更方便的HttpServlet类,来编写一个Servlet
import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("my first servlet!");
}
}
注册Servlet可以使用注解或手动配置web.xml文件,我们这里使用注解来配置。部署并启动tomcat服务后,访问http://localhost:8080/test/TestServlet即可触发doGet方法
Filter
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。Filter可以拦截所有访问web资源的请求或响应操作,并可以再拦截后对请求或相应进行修改。
Filter的生命周期
Filter的生命周期分为如下三部分:
- 初始化阶段:init(FilterConfig),初始化方法,只会在web应用程序启动时调用一次。
- 拦截和过滤阶段:doFilter(ServletRequest, ServletResponse, FilterChain),完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。引入的FilterChain对象提供了后续过滤器所要调用的信息。如果该过滤器是过滤器链中的最后一个过滤器,则将请求交给被请求资源。也可以直接给客户端返回响应信息。
- 销毁阶段:destory(),销毁Filter,只会在当web应用移除或服务器停止时才调用一次来卸载Filter对象
Filter的简单使用
接下来我们编写一个简单的Filter
跟Servlet类似,Filter需要实现Filter接口,这里重点的就是doFilter方法的重写,其包含了此Filter处理数据的全部逻辑
我们简单编写一个Filter类
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/TestServlet")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("调用了Filter!");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
Filter的注册方式与执行顺序
Filter的配置方式有两种,分别是使用注解和在xml中配置,注册方式不同,Filter的执行顺序也有所不同
-
基于注解配置:在自定义的Filter类上使用注解@WebFilter(“/*”),按照类名的字符串比较规则比较,值小的先执行
-
在web.xml中配置:
filtername com.it.web.filter.SecondFilter filtername /* 根据在web.xml中的配置顺序进行执行
我们这里使用注解进行配置,当我们访问该过滤器指定的路径时,Filter自动触发
Listener
Listener是用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生变化时,立即采取相应的行动。
Listener的分类
Servlet规范中提供了8个常用的监听器,一般分为以下三种:
ServletContext
:在服务启动和终止时触发Session
:有关Session操作时触发Request
:访问服务时触发
listener的简单使用
接下来我们编写一个简单的ServletRequestListener监听器
ServletRequestListener接口用于实现监听ServletRequest
对象的创建和销毁
我们创建一个类继承此接口并实现其方法
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
@WebListener
public class TestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("destroyde TestListener");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("initializde TestListener");
}
}
同样,Listener的注册方式也为两种,分别是使用注解和在web.xml中注册
我们在上面的代码中使用的注解注册,当我们随便访问一个资源时,便会触发Listener
三者的执行顺序
三者的加载顺序为Listener->Filter->Servlet
参考: