Servlet 之超详解【2023年最新版】(一)

简介: Servlet 之超详解【2023年最新版】(一)

编译软件:IntelliJ IDEA 2019.2.4 x64

操作系统:win10 x64 位 家庭版

服务器软件:apache-tomcat-8.5.27


一. 什么是Servlet?

Servlet,英文全称为Server Applet,意为服务器端的一小程序。它运行在支持Java Servlet规范的Web服务器上。在服务器上部署的众多web应用程序中,无论它是B/S架构,还是C/S架构,它们的基本运行模式如下图所示(以Java程序为例):

如果把上述web应用的运行模式比作是一个正在在营业的餐厅,那Servlet在其中扮演着服务员的角色,客人进店吃饭(客户端发出请求),它负责给客人上菜单,等客人点好菜单,servlet就会通知厨子(web应用)做菜(处理业务),厨子做好菜,就让服务员去上菜(响应)给客人。

总的来说,Servlet就是和客户端进行交互(处理请求和响应)

Servlet通常被用于创建像电子商务网站、社交媒体应用、在线银行网站等类似的Web应用程序。通过使用Servlet,开发人员可以以一种可移植、灵活、高效和可重用的方式构建Web应用程序。


二. 如何编写第一个servlet程序?

步骤:

①创建一个html页面,在上面创建一个超链接(计划访问后台的HelloServlet)

<a href="">访问HelloServlet</a>

②创建HelloServlet

  1. 新建一个普通类HelloServelet
  2. HelloServelet实现接口Servlet
  3. 实现接口中的所有抽象方法

代码演示如下:

import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    /**
     * 主要功能:处理客户端的请求和响应
     * @param servletRequest  处理请求
     * @param servletResponse  处理响应
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("访问了HelloServlet类的service方法.......");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
}
  1. 在web.xml中为HelloServlet设置访问路径

代码演示如下:

<!--  HelloServlet的访问路径:/hello  -->
<servlet>
    <!--   为Servlet起个名字     -->
    <servlet-name>abc</servlet-name>
    <!--   Servlet的全类名     -->
    <servlet-class>t1.HelloServelet</servlet-class>
</servlet>
<servlet-mapping>
    <!--  要和Servlet中的servlet-name的名字一致      -->
    <servlet-name>abc</servlet-name>
    <!--   设置访问路径,注意,必须是/开头     -->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

③将设置到的访问路径设置给超链接

<a href="hello">访问HelloServlet</a>

④测试HelloServelt

注意:

  1. 网页必须直接在web下(不能放在WEB-INF下)
  2. web.xml中url-pattern的值必须以/开头
  3. 网页的请求路径,不能以/开头
  4. 网页不能采用静态的打开方式

请求原理如下所示:

Servlet的对象管理:

  • Servlet的实例对象由Servlet容器(tomcat)负责创建
  • Servlet的方法由容器在特定情况下调用
  • Servlet容器会在web应用卸载时(tomcat停止)销毁Servlet对象的实例

三. Servlet的生命周期

Servlet接口中一共有五个方法,其中有三个和生命周期有(init/service/destroy)的方法。

请求过程:

  1. 默认情况下在第一次发出请求时,Servlet容器(tomcat服务器)会创建相应的servlet对象、进行初始化(执行init方法)、执行service方法
  2. 第二次以及以后的每一次请求发出,都直接执行service方法
  3. 在web应用被卸载(服务器被停止时)的时候,servlet对象会被销毁,销毁之前执行destroy方法

Servlet可以在启动服务器时就创建其对象吗?

可以

方法如下:

在web-xml中当前Servlet的servlet标签内添加标签

//设置自启动
<load-on-startup>l</1oad-on-startup>

代码演示如下:

<!--   设置自启动,若有多个servlet都设了自启动,根据标签体中的值来判定启动优先级,值越小,优先级越高     -->
<!--     <load-on-startup></load-on-startup>中的标签体为非0的整数     -->
        <load-on-startup>1</load-on-startup>

四. Servlet的技术体系

创建Servlet的三种方式:

①实现Servlet接口

重写其五个方法(重点关注的只有一个service),其他四个还必须重写

案例:创建HelloServelet 类实现Servlet 接口

代码演示如下:

import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    /**
     * 主要功能:处理客户端的请求和响应
     * @param servletRequest  处理请求
     * @param servletResponse  处理响应
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("访问了HelloServlet类的service方法.......");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
}

web-xml创建其访问路径:

<!--  HelloServlet的访问路径:/hello  -->
<servlet>
    <!--   为Servlet起个名字     -->
    <servlet-name>abc</servlet-name>
    <!--   Servlet的全类名     -->
    <servlet-class>t1.HelloServelet</servlet-class>
</servlet>
<servlet-mapping>
    <!--  要和Servlet中的servlet-name的名字一致      -->
    <servlet-name>abc</servlet-name>
    <!--   设置访问路径,注意,必须是/开头     -->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

②继承GenericServlet

步骤:

  1. 创建一个类
  2. 继承一个抽象类(GenericServlet)
  3. 实现抽象类中的抽象方法
  4. 在web-xml中配置Servlet的访问路径

注意:

GenericServlet主要的功能是将service以外的四个方法做了实现。我们自己的Servlet只需要实现service方法即可,如果想用其他的四个方法,可以采用重写。

案例:创建MyFirstServlet类继承GenericServlet类

代码演示如下:

public class MyFirstServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("触发了继承GenericServlet类的子类MyFirstServlet类的service方法......");
    }
}

web-xm配置其访问路径:

<!-- 设置访问MyFirstServlet的路径:/myfirst   -->
    <servlet>
        <servlet-name>def</servlet-name>
        <servlet-class>t1.MyFirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>def</servlet-name>
        <url-pattern>/myfirst</url-pattern>
    </servlet-mapping>

③继承HttpServlet

步骤:

  1. 创建一个类
  2. 继承一个抽象类(HttpServlet)
  3. 重写两个方法doGet和doPost
  4. 配置Servlet的访问路径

注意:

HttpServlet主要功能是实现service方法,然后对请求进行分发的操作(不同的请求方式调用不同的方法)。get请求调用doGet方法post请求调用doPost方法

案例:创建MyFirstServlet类继承GenericServlet类

代码演示如下:

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SecondServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("访问了SecondServlet里的doPost方法");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("访问了SecondServlet里的doGet方法");
    }
}

web-xm配置其访问路径:

<!-- 设置访问SecondServlet的路径:/second   -->
    <servlet>
        <servlet-name>SecondServlet</servlet-name>
        <servlet-class>t1.SecondServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SecondServlet</servlet-name>
        <url-pattern>/second</url-pattern>
    </servlet-mapping>


五. web项目中的两个接口

5.1 Servletconfig接口

一个Servlet对象对应唯一的一个ServletConfigi配置对象

Servletconfig对象如何获得?

在init方法的形参位置,Servletconfig是在当前Servlet进行初始化的时候,传递给init方法的

主要功能:

  1. 获取Servlet名称(web.xml中servlet-name的值)
//获取Servlet名称
   String servletName = servletConfig.getServletName();
   System.out.println("servletName:"+servletName);
  1. 获取全局上下文(ServletContext)对象
//获取全局上下文对象
ServletContext servletContext = servletConfig.getServletContext();
System.out.println("servletContext:"+servletContext);
  1. 获取Servlet初始化参数

获取Servlet初始化参数的前提是要有servlet的初始化参数

  1. 如何设置servlet的初始化参数?
    位置:web.xml的servlet标签内,在子标签1–>之上设置,不然报错
    代码演示如下:
<!--设置当前Servlet的初始化参数-->
     <init-param>
     <param-name>path</param-name>
     <param-value>classpath:springmvc.xml</param-value>
     </init-param>
  1. 获取Servlet初始化参数:
//获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值
     String path = servletConfig.getInitParameter("path");
     System.out.println("path:"+path);
     //获取HelloServelet内所有初始化参数的<param-name>【key】值
     Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
     while (initParameterNames.hasMoreElements()){
           System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement());
     }

案例:在HelloServelet类实现上述功能

代码演示如下:

import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloServelet implements Servlet {
    public HelloServelet() {
        System.out.println("HelloServelet类的构造方法被执行了");
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("HelloServelet类的init方法被执行了");
        //1.获取的是当前Servlet名称(web.xml中配置servlet-name的值)
        String servletName = servletConfig.getServletName();
        System.out.println("servletName:"+servletName);
        //2.获取全局上下文ServletContext对象
        ServletContext servletContext = servletConfig.getServletContext();
        System.out.println("servletContext:"+servletContext);
        //3.获取Servlet初始化参数
        //获取web-xml中的servlet标签内的初始化参数<param-name>为path的value值
        String path = servletConfig.getInitParameter("path");
        System.out.println("path:"+path);
        //获取web-xml中的初始化参数<param-name>为aaa的value值
        String aaa = servletConfig.getInitParameter("aaa");
        System.out.println("aaa:"+aaa);
        //获取HelloServelet内所有初始化参数的<param-name>【key】值
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()){
            System.out.println("initParameterNames.nextElement():"+initParameterNames.nextElement());
        }
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    /**
     * 主要功能:处理客户端的请求和响应
     * @param servletRequest  处理请求
     * @param servletResponse  处理响应
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("访问了HelloServlet类的service方法.......");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("HelloServelet类的destroy方法被执行了");
    }
}

相关文章
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
【Shell 命令集合 系统设置 】⭐⭐⭐Linux 清除终端屏幕内容 clear命令 使用指南
587 0
|
12月前
|
数据采集 JSON 监控
速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)
以下是使用 Python 调用速卖通商品列表接口(以 AliExpress Affiliate 商品查询 API 为例)的代码示例。该示例包含准备基础参数、生成签名、发送请求和处理响应等关键步骤,并附有详细注释说明。代码展示了如何通过公共参数和业务参数构建请求,使用 HMAC-SHA256 加密生成签名,确保请求的安全性。最后,解析 JSON 响应并输出商品信息。此接口适用于商品监控、数据采集与分析及商品推荐等场景。注意需通过 OAuth2.0 获取 `access_token`,并根据官方文档调整参数和频率限制。
|
12月前
|
人工智能 自然语言处理 算法
DeepSeek模型的突破:性能超越R1满血版的关键技术解析
上海AI实验室周伯文团队的最新研究显示,7B版本的DeepSeek模型在性能上超越了R1满血版。该成果强调了计算最优Test-Time Scaling的重要性,并提出了一种创新的“弱到强”优化监督机制的研究思路,区别于传统的“从强到弱”策略。这一方法不仅提升了模型性能,还为未来AI研究提供了新方向。
1578 9
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础
|
Java 网络安全
zookeeper的环境搭建和配置
本文介绍了如何在多台节点上搭建和配置Zookeeper环境。内容包括Zookeeper的下载、解压、环境变量配置、配置文件修改、zkdata目录创建、myid文件设置,以及将Zookeeper及其配置文件复制到其他节点。还提供了运行测试的命令,包括启动、状态检查和停止Zookeeper服务。
zookeeper的环境搭建和配置
|
消息中间件 Kafka 网络安全
消息中间件系列教程(20) -Kafka-集群搭建
消息中间件系列教程(20) -Kafka-集群搭建
439 0
|
消息中间件 存储 负载均衡
【赵渝强老师】Kafka的体系架构
Kafka消息系统是一个分布式系统,包含生产者、消费者、Broker和ZooKeeper。生产者将消息发送到Broker,消费者从Broker中拉取消息并处理。主题按分区存储,每个分区有唯一的偏移量地址,确保消息顺序。Kafka支持负载均衡和容错。视频讲解和术语表进一步帮助理解。
293 0
|
开发框架 前端开发 Java
【Spring】Spring框架介绍,功能模块,容器知识和有关Spring的生态圈的详细讲解
【Spring】Spring框架介绍,功能模块,容器知识和有关Spring的生态圈的详细讲解
568 0
|
负载均衡 前端开发 Java
OpenFeign:Spring Cloud声明式服务调用组件
该文本是关于OpenFeign在Spring Cloud中的使用的问答总结。涉及的问题包括:OpenFeign是什么,Feign与OpenFeign的区别,如何使用OpenFeign进行远程服务调用,OpenFeign的超时控制以及日志增强。OpenFeign被描述为Spring官方的声明式服务调用和负载均衡组件,它支持使用注解进行接口定义和服务调用,如@FeignClient和@EnableFeignClients。OpenFeign与Feign的主要区别在于OpenFeign支持Spring MVC注解。超时控制通过Ribbon进行设置,默认超时时间为1秒。
231 1
|
监控 搜索推荐 算法
Java排序:原理、实现与应用
【4月更文挑战第28天】本文探讨了Java中的排序算法,包括原理和实现。Java利用Comparator接口进行元素比较,通过Arrays和Collections类的sort方法对数组和列表进行排序。示例展示了使用这些方法的基本代码。此外,还讨论了冒泡排序算法和自定义排序场景,以适应不同需求。理解这些排序机制有助于提升程序效率。
261 1