Servlet

1. Servlet 的概念

Servlet(Server Applet),它是运行在服务器端的小程序。

实际上 Servlet 就是一个接口,定义了 Java 类能被 Tomcat 识别的规则。(也就是说我们自定义一个 java 类,它实现了 Servlet 接口,它就能被 Tomcat 识别了)

2. Servlet 快速入门

  1. 创建一个 JavaEE 项目

  2. 定义一个 Java 类,并且实现 Servlet 接口

  3. 实现 Servlet 接口中的方法

    package com.zt.web.servlet;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    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");
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
  4. 配置 Servlet

    在web.xml中配置:

    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    <!--配置 Servlet-->
    <servlet>
        <!--给 Servlet 起一个名字,一般和类名一致-->
        <servlet-name>ServletDemo1</servlet-name>
        <!--配置这个 Servlet 的全类名-->
        <servlet-class>com.zt.web.servlet.ServletDemo1</servlet-class>
    </servlet>
    <!--配置 Servlet 的映射路径-->
    <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <!--外界能访问到 Servlet 的资源路径-->
        <url-pattern>/ServletDemo1</url-pattern>
    </servlet-mapping>
    </web-app>
    
  5. 访问项目

    1. 启动服务器

    2. 打开浏览器,在地址栏输入

      http://localhost:8080/ServletDemo1
      
    3. 此时控制台会输出

      hello
      

3. Servlet 的执行原理

疑问:

在上面的实例中,我们创建了 ServletDemo1 这个类,并且实现了 Servlet 接口,但我们并没有创建 ServletDemo1 的对象,那 service 方法(不是静态方法)是怎么就被执行了呢?

Servlet 的执行原理如下:

  1. 当服务器接受到客户端浏览器的请求后,会解析请求 URL 路径,获取访问的 Servlet 的资源路径
  2. 然后查找 web.xml 文件,是否有与资源路径对应的 <url-pattern> 标签体内容。
  3. 如果有,则在找到对应的 <servlet-class> 全类名
  4. Tomcat 会将全类名对应的字节码文件加载进内存,并且创建其对象,调用 service 方法

在这里插入图片描述

4. Servlet 的生命周期

  1. 被创建

    Servlet 被创建时,执行 init 方法,只执行一次(一般用于加载资源)

    1. Servlet 什么时候被创建?

      默认情况下,第一次被访问时,Servlet 被创建

    2. 配置执行 Servlet 的创建时机

      <servlet> 标签中配置

      1. 第一次被访问时,Servlet 被创建

        <load-on-startup>负数</load-on-startup>
        
      2. 在服务器启动时,Servlet 被创建

        <load-on-startup>0或正整数</load-on-startup>
        
    3. Servlet 的 init 方法,只执行一次,说明一个 Servlet 在内存中只存在一个对象,Servlet 是单例的

      问题:多个用户同时访问时,可能存在线程安全问题

      解决办法:尽量不要在 Servlet 中定义成员变量。即使定义了成员变量,也不要对修改值

  2. 提供服务

    每一次 Servlet 被访问时,执行 service 方法,执行多次

  3. 被销毁

    在服务器正常关闭时,执行 destroy 方法,只执行一次(一般用于释放资源。)

5. Servlet 3.0

  1. 功能

    支持注解配置,可以不用 web.xml 配置了。

  2. 使用步骤

    1. 点击 Create New Project

    2. 选择 Java Enterprise

    3. Java EE version 修改为 Java EE 7 及以上

    4. 勾选 Web Application,选择 Servlet 的版本 3.0 及以上,可以不勾选创建 web.xml,点击 Next

    5. 输入 Project Name,点击 Finish

    6. 定义一个 Java 类,并且实现 Servlet 接口

    7. 实现 Servlet 接口中的方法

    8. 在类上使用 @WebServlet 注解,进行配置

      // 定义一个访问路径
      @WebServlet("资源路径") 
      // 定义多个访问路径
      @WebServlet({"资源路径1","资源路径2","资源路径3"})
      
    9. 访问项目

      1. 启动服务器

      2. 打开浏览器,在地址栏输入

        http://localhost:8080/资源路径
        

6. Servlet 的体系结构

我们使用 Servlet 类时,往往只需要使用 service 方法,但我们却不得不实现 Servlet 接口中的所有方法,这样会出现很多冗余代码。Java EE 中 Servlet 接口有两个实现类,可以解决这一问题。

Servlet 的体系结构:

Servlet -- 接口
	| 
GenericServlet -- 实现 Servlet 接口的抽象类
	|
HttpServlet  -- 实现 Servlet 接口的抽象类
  1. GenericServlet

    GenericServlet 类将 Servlet 接口中其他的方法做了默认空实现,只将 service() 方法作为抽象方法。将来定义 Servlet 类时,可以继承 GenericServlet,只需实现 service() 方法。

    package com.zt.web.servlet;
    
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    import java.io.IOException;
    
    @WebServlet("/ServletDemo2")
    public class ServletDemo2 extends GenericServlet {
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("GenericServlet...");
        }
    }
    
  2. HttpServlet

    在 service 方法中,获取数据之前,先要判断请求方式

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// 获取请求方式
    	String method = req.getMethod();
        // 判断请求方式
    	if(method.equals("GET")){
    		// Get 方式获取数据
    	}
        if(method.equals("POST")){
    		// Post 方式获取数据
    	}
    }
    

    上面这个过程十分麻烦,但也是不能省略的,所以 Java EE 中提供了 HttpServlet 。在 service 方法中,它帮我们判断请求方式是 GET 还是 POST,并做了一个方法的分发,如果是 GET 就调用 doGet 方法,如果是 POST 就调用 doPost 方法。

    将来定义 Servlet 类时,可以继承 HttpServlet,就只用重写 doGet 和 doPost 方法即可,不用再去重写 service 了。

    package com.zt.web.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("/ServletDemo3")
    public class ServletDemo3 extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost...");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doGet...");
        }
    }
    
    

    补充:浏览器直接访问 Servlet 是 Get 方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值