Servlet是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,是一个Java类。
一个 Servlet 总是继承自 HttpServlet ,然后覆写 doGet() 或 doPost() 方法。注意到 doGet() 方法 传入了 HttpServletRequest 和 HttpServletResponse 两个对象,分别代表 HTTP 请求和响应。我们使用 Servlet API 时,并不直接与底层 TCP 交互,也不需要解析 HTTP 协议,因为 HttpServletReque st 和 HttpServletResponse 就已经封装好了请求和响应。以发送响应为例,我们只需要设置正确的响应 类型,然后获取 PrintWriter ,写入响应即可。
而这样的一个项目最终会打包成一个*.war文件,运行这个文件,需要使用支持ServletAPI的Web容器(Web服务器)。这里我们选择使用最广泛的开源免费的Tomcat服务器。
在通过一个 URL 路径发起对一个 Servlet 请求的过程中,其本质是在调用执行 Servlet 实例的 doX XX() 方法。该 Servlet 实例创建和使用的过程,被称为Servlet的生命周期。整个生命周期包括:实例化、初始化、服务、销毁。
根据 Servlet 请求的路径,查找该 Servlet 的实例。实例存在则直接使用;如果实例不存在,则通过调用构造方法,完成 Servlet 实例的创建。
- //WebServlet注解表示这是一个Servlet,并映射到地址 hello.do
- @WebServlet("/home.do")
- public class HomeServlet extends HttpServlet{
-
- // 1.实例化
- // 构造方法
- public HomeServlet() {
- System.out.println("1.HomeServlet实例被创建");
- }
通过该 Servlet 的实例,调用 init() 方法,执行初始化的逻辑。在 Servlet 的整个生命周期内,它的 init() 方法只能被调用一次。
- // 2.初始化
- // 重写HttpServlet父类的init()方法
- // 通过实例自动调用init()方法
- @Override
- public void init() throws ServletException {
- System.out.println("2.HttpServlet实例初始化");
- }
通过该 Servlet 的实例,调用 service() 方法,如果子类没有重写该方法,则调 用HttpServlet父类的 service() 方法,在父类的该方法中进行请求方式的判断, 如果是 GET 请求,则调用 doGet() 方法;如果是 POST 请求,则调用 doPost () 方法; 如果子类重写 doXXX() 方法,则调用子类重写后的 doXXX() 方法; 如果子类没有重写 doXXX() 方法,则调用父类的 doXXX() 方法,在父类的方法实现中,返回一个 405 状态码(代表请求的方式服务器不提供支持)的错误页面。
- // 3.服务
- // 通过实例调用HttpServlet父类的service()方法
- // service()方法中,会根据请求方式(get或post)的不同
- // 调用子类重写的doGet()或doPost()
- // 如果子类没有重写,则响应405
-
- // 根据请求方式的不同,需要调用不同的请求方法
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("homeServlet被GET请求到了" + this.hashCode());
- String method = req.getMethod();
- System.out.println("请求方式:" + method);
-
- }
服务器关闭或重启时,会销毁所有的Servlet实例,会调用Servlet实例的destroy()方法。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。
- // 4.销毁
- @Override
- public void destroy() {
- System.out.println("4.HomeServlet实例被销毁");
- }
在浏览器输入 http://localhost:8080/项目名称/home.do ,即可看到 HomeServlet 的输出。
为什么路径是 "/项目名称" 而不是 / ?因为一个 Web 服务器允许同时运行多个 Web App 。因此,第一级目录 /项目名称表示Web App的名字,后面的 /home.do 才是我们在 HelloServlet 中映射的路径。
