Servlet详解

Servlet是Java服务小程序,由服务器如Tomcat调用执行。它按照Servlet规范开发,功能强大,可处理各种网站功能。Servlet生命周期包括装载、处理请求及终止阶段。在Web.xml中,<load-on-startup>标签用于设置Servlet初始化顺序,正整数表示优先级,负数或零则在第一次请求时初始化。此外,文章还介绍了通过注解方式配置Servlet的方法。
摘要由CSDN通过智能技术生成

什么是Servlet

Servlet在开发动态Web工程中,得到广泛的应用,掌握好Servlet非常重要,Servlet是SpringMVC的基石

Servlet(Java服务小程序) 特点

○ 它是由服务端调用和执行的(一句话: Tomcat解析和执行)
○ 它是用Java语言编写的,本质就是Java类
○ 它是按照Servlet规范开发的(除了tomcat->Servlet weblogic->servlet)
○ 功能强大,可以完成几乎所有的网站功能

Servlet生命周期

○ Servlet容器(Tomcat)启动时自动装载某些Servlet,实现这个需要在Web.xml文件中添加<load-on-startup>1</load-on-startup>表示装载的顺序
○ 在Servlet容器启动后,浏览器首次向Servlet发送请求
○ Servlet重新装载时(比如tomcat进行redeploy【redeploy会销毁所有的Servlet实例】),浏览器再向Servlet发送请求的第一次、

处理浏览器请求阶段(Service方法)

○ 每收到一个Http请求,服务器就会产生一个新的线程去处理【线程】
○ 创建一个用于封装Http请求消息的ServletRequest对象和一个代表HTTP响应消息ServletResponse对象
○ 然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去

终止阶段

当Web应用被终止,或Servlet容器终止运行,或者Servlet类重新装载时,会调用destory()方法

在Java的Web应用程序中,<load-on-startup>1</load-on-startup>是一种配置参数,用于指定一个Servlet在Web应用程序启动时自动加载并初始化的顺序。

具体来说,<load-on-startup>元素是在 web.xml 文件中用来配置 Servlet 的初始化顺序的。它的值可以是一个正整数,也可以是负整数或零。这个值表示 Servlet 初始化的优先级,数字越小,优先级越高。

如果 <load-on-startup>的值是一个正整数,表示需要按照指定的顺序来初始化 Servlet。例如,<load-on-startup>1</load-on-startup> 表示该 Servlet 拥有最高优先级,会在其他没有指定 <load-on-startup> 或者值较大的 Servlet 之前被初始化。

如果 <load-on-startup>的值是负整数或零,表示该 Servlet 不会自动加载,需要在第一次请求该 Servlet 时进行初始化。例如,<load-on-startup>0</load-on-startup>表示该 Servlet 不会在启动时自动加载,而是在第一次访问时才会进行初始化。
在这里插入图片描述

在这里插入图片描述
浏览器请求流程分析

Servlet通过Web.xml配置使用

public class HelloServlet implements Servlet {
    /**
     * 初始化
     * 当Tomcat创建HelloServlet实例时,会调用initi方法
     * 该方法只会调用一次
     * @param servletConfig
     * @throws ServletException
     */
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    /**
     * @return 返回ServletConfig 也就是返回Servlet的配置
     */
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * 1. service方法会接收两个参数处理浏览器get/post请求
     * 2. 浏览器每次请求Servlet时,就会调用service方法
     * 3. 当Tomcat调用该方法时,会把HTTP请求的数据封装成实现了ServletRequest接口的request对象
     * 4. 通过servletRequest对象可以得到用户提交的数据
     * 5. servletResponse对象可以用于返回数据给Tomcat->浏览器
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("service方法被调用了");
    }

    /**
     * @return返回Servlet的信息
     */
    public String getServletInfo() {
        return null;
    }

    /**
     * servlet销毁时被调用只会被调用一次
     */
    public void destroy() {

    }
}

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <!--web.xml主要用来配置web应用使用到的Servlet-->
    <!--配置HelloServlet-->
    <!--servlet-name: 给Servlet取名 该名字唯一-->
    <!--servlet-class: Servlet的类的全路径: Tomcat在反射生成该Servlet需要使用-->
    <!--url-pattern:这个就是该Servlet访问的url配置的路径-->
    <!--我们应该这样访问servlet http://localhost:8080/helloServlet如果你的tomcat配置只有/的话那么是这个,如果/后面有内容加上/后面的-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>HiServlet</servlet-name>
        <servlet-class>HiServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HiServlet</servlet-name>
        <url-pattern>/hiServlet</url-pattern>
    </servlet-mapping>
</web-app>

如果是第一次请求(Tomcat)

  1. 查看web.xml
  2. 看看请求的资源/helloServlet,在web.xml配置url-pattern
  3. 如果找到url-pattern,就会得到servlet-name HelloServlet
  4. Tomcat维护了一个大的HashMap<id,Servlet>,查询该HashMap,看看有没有这个Servlet实例
  5. 如果没有查询到该Servletname对应的id,即没有这个Servlet实例
  6. 就根据Servlet-name去得到servlet-class:类的全路径
  7. 使用反射技术,将Servlet实例化->init(),并放入到Tomcat维护的HashMap<id,Servlet>

Servlet通过注解的方式使用

在项目的根目录下创建Annnotation包,在该包下创建一个Servlet

/**
 * 注解方式来配置
 * @WebServlet 是一个注解 => Java基础 注解
 * urlPattern对应web.xml的<url-pattern></url-pattern>
 * @WebServlet(urlPatterns = {"/s1", "/s2"}) 代替了web.xml配置
 * 浏览器可以这样访问SparrowServlet 可以http://localhost:8080/s1 或/s2来访问
 * 底层使用了反射 +注解+IO+集合来支撑
 * 注解方式开发Servlet和web.xml配置Servlet流程机制是一样的
 * crtl + alt + ->快捷键
 **/
@WebServlet(urlPatterns = {"/s1", "/s2"})
public class SparrowServlet 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被调用了");
    }
}

为什么加上个@WebServlet注解就能访问到servlet呢?接下来我们模拟一下Tomcat的执行流程

/**
 * @Author: 诉衷情の麻雀
 * 模拟Tomcat是如果通过@WebServlet(urlPatterns = {"/s1","/s2"})
 * 来装载一个Servlet的
 **/
public class TestAnnotationServlet {
    private static final HashMap<String, Object> hashMap= new HashMap<>();


    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //1. 首先要得到扫描的包
        String classAllPath = "com.sparrow.servlet.annotation.SparrowServlet";
        //2.得到OkServlet的Class对象
        Class<?> aClass = Class.forName(classAllPath);
        //3.通过class对象,得到Annotation
        WebServlet annotation = aClass.getAnnotation(WebServlet.class);
        System.out.println(annotation);
        String[] strings = annotation.urlPatterns();
        for (String url : strings) {
            System.out.println("url = " + url);
        }

        //如果匹配url,如果是第一次,tomcat就会创建一个SparrowServlet实例,放入到HashMap中
        //为什么要放入到HashMap中,方便以后再次调用,因为Servlet是单例化的,在内存中只有一份
        Object instance = aClass.newInstance();
        System.out.println("instance" + instance); //SparrowServlet
        //简单的模拟
        hashMap.put("SparrowServlet", instance);
        System.out.println(hashMap);
    }
}

控制台输入信息如下:
在这里插入图片描述
在这里插入图片描述
当我们在浏览器输入http://localhost:8080/s1 还是http://localhost:8080/s2都是能访问到的。
这是通过注解的方式配置Servlet

温馨提示
Servlet配置了"/**"表示可以匹配任意访问路径
建议不要使用/和 /,建议使用精准匹配,因为Tomcat默认的Servlet的配置是/ ,如果你配置了/ 会拦截所有的请求
优先级遵守: 精确路径 > 目录路径 > 扩展名路径 > /
> /

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

诉衷情の麻雀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值