Servlet

Servlet是Java EE中用于处理客户端请求的接口,定义了服务器端小程序的规范。本文详细介绍了Servlet的创建步骤,包括实现Servlet接口、配置web.xml,以及执行流程,从服务器接收请求到返回HTTP响应的过程。同时,阐述了Servlet的生命周期,包括被创建、提供服务和被销毁的阶段,并提及了Servlet的单例性质和线程安全问题。还涵盖了Servlet的继承体系,包括Servlet、GenericServlet和HttpServlet,以及Servlet 3.0的注解配置优势。最后,讨论了IDEA InteliJ与Tomcat的配置和调试要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Github:servlet_demo

一. 定义

servlet-api:https://tomcat.apache.org/tomcat-8.5-doc/servletapi/index.html

Servlet(Server Applet,运行在服务器端的小程序),是一个接口,定义了 Java 类被浏览器访问到(Tomcat 识别)的规则。我们需要自定义一个类实现 Servlet 接口并重写其方法。

二. 创建步骤

1.创建 JavaEE 项目

2.创建一个类并实现 Servlet 接口:public class ServletDemo1 implements Servlet

3.实现 Servlet 接口中的抽象方法

import javax.servlet.*;
import java.io.IOException;

/**
 * ServletDemo1:Servlet 快速入门
 */
public class ServletDemo1 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException { 
    
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    // 提供服务的方法
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello Servlet!");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

4.在 web.xml 中配置 Servlet

<!-- 配置 Servlet -->
<servlet>
	<servlet-name>demo1</servlet-name>
	<servlet-class>com.hjplz.web.servlet.ServletDemo1</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>demo1</servlet-name>
	<url-pattern>/demo1</url-pattern>
</servlet-mapping>

三. 执行流程

Servlet执行流程
1.当服务器接收到客户端浏览器的请求后,会解析请求 URL 路径,获取访问 Servlet 的资源路径。

2.服务器查找在 web.xml 中 <url-pattern> 是否有对应的路径。

3.如果有,通过映射找到 <servlet-class> 全类名。

4.Tomcat 将全类名对应的字节码文件加载进内存:Class.forName() ,并创建其对象:newInstance()

5.调用 service() 方法

6.将处理结果封装到 response 对象,服务器从此对象中获取信息,给客户端浏览器返回 HTTP 响应。

注意,多个请求创建多个线程来处理。
在这里插入图片描述

四. 生命周期

Servlet生命周期
1.被创建:init() ,只执行一次。

  • 默认情况:第一次被访问时创建 Servlet
  • 可以通过在 <servlet> 标签下配置来指定 Servlet 的创建时机
    <!-- 指定 Servlet 的创建时机
    	1. 第一次被访问时创建:<load-on-startup> 的值为负数(默认为 -1)
        2. 在服务器启动时创建:<load-on-startup> 的值为非负数
    -->
    <load-on-startup>-1(default)</load-on-startup>
    
  • init() 只执行一次说明一个 Servlet 在内存中只存在一个对象,Servlet 是单例的。
    • 多个用户同时访问时,可能存在线程安全问题。
    • 解决方法:尽量不要在 Servlet 中定义成员变量,即使定义了成员变量,也不要修改其值。

2.提供服务:service() ,可以执行多次。

  • 每次访问 Servlet 时,service() 都会被调用一次。

3.被销毁:destroy() ,只执行一次。

  • 服务器关闭时,Servlet 被销毁。如果服务器不是正常关闭则不会执行此方法。
  • 在 Servlet 被销毁之前执行,一般用于释放资源。
import javax.servlet.*;
import java.io.IOException;

/**
 * ServletDemo2:Servlet 方法(生命周期)
 */
public class ServletDemo2 implements Servlet {

    /**
     * 初始化方法
     * 在 Servlet 被创建时执行,只会执行一次。
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init...");
    }

    /**
     * 获取 ServletConfig 对象(Servlet 配置对象)
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 提供服务方法
     * 每一次 Servlet 被访问时执行,可以执行多次。
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service...");
    }

    /**
     * 获取 Servlet 信息:version、author...
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法
     * 在服务器正常关闭时执行,只会执行一次。
     */
    @Override
    public void destroy() {
        System.out.println("destroy...");
    }
}

五. Servlet 继承体系结构

1.Servlet(接口)— GenericServlet(抽象类)— HttpServlet(抽象类)

2.GenericServlet:将 Servlet 接口中其他方法做了默认空实现,只把 service() 抽象。

  • 定义 Servlet 类继承 GenericServlet,只要实现 service() 即可。
    import javax.servlet.*;
    import javax.servlet.annotation.WebServlet;
    import java.io.IOException;
    
    /**
     * 继承抽象类 GenericServlet
     */
    @WebServlet("/demo4")
    public class ServletDemo4 extends GenericServlet {
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("GenericServlet...");
        }
    }
    

3.HttpServlet:对HTTP协议进行封装,简化操作。

  • 定义 Servlet 类继承 HttpServlet,重写 doGet() & doPost()
    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;
    
    /**
     * 继承抽象类 HttpServlet
     */
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doGet...");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost...");
        }
    }
    

六. Servlet 3.0

1.优点:支持注解配置,不再需要 web.xml。

2.注解配置:在类上使用 @WebServlet("url-pattern") ,e.g. @WebServlet("/demo3")

  • 虚拟目录 Application context 是项目的访问地址,资源路径 url-pattern 是 Servlet 类的访问地址。
  • 一个 Servlet 可以定义多个访问路径:@WebServlet({"/path1", "/path2", ...})
  • 路径定义规则
    • 精准匹配:/foo.htm 只会匹配 foo.htm 这个 URL
    • 路径匹配:/foo/* 会匹配以 foo 为前缀的 URL
    • 后缀匹配:*.htm 会匹配所有以 .htm 为后缀的 URL
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;

/**
 * Servlet 路径配置
 */
// @WebServlet({"/demo6", "/d6"})
// @WebServlet("/*")
// @WebServlet("/user/*")
// @WebServlet("/user/demo6")
// @WebServlet("*.do")
@WebServlet("/demo6")
public class ServletDemo6 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo6...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo6...");
    }
}

七. IDEA InteliJ & Tomcat 的相关配置

1.IDEA InteliJ 会为每一个 Tomcat 部署的项目单独创建一份配置文件

  • 查看控制台log:org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /Users/mac/Library/Caches/IntelliJIdea2019.2/tomcat/Tomcat_8_5_45_servlet_demo

2.工作空间项目 & Tomcat 部署的 web 项目

  • Tomcat 真正访问的是部署的 web 项目,其对应着工作空间项目 web 目录下的所有资源。
  • WEB-INF 目录下的资源(classes 目录、lib 目录、web.xml)不能直接被浏览器访问。

3.断点调试:Debug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值