Java研学-Servlet 基础

一 概述

1 介绍

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

狭义的 Servlet 是指Java语言实现的一个接口,广义的 Servlet 是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

Servlet 本质为运行在 Web服务器(如Tomcat服务器)的,使用 Java编写的小应用程序。

2 作用

接收浏览器请求并响应数据给浏览器。开发动态资源:Servlet 也是服务器的一种资源,可以供外界(浏览器)去访问。

3 开发步骤

java 复制代码
1. 创建一个类实现 javax.servlet.Servlet 接口
2. 实现接口中的所有方法
3. 在 service 方法处理请求和响应数据
4. 配置 Servlet 的访问地址(供外界:浏览器访问)
可以通过 web.xml 文件配置,也可以通过注解配置

4 若找不到Servlet

① 打开project Structure,找到Modules

② 选择模块

③ 点击Dependencies

④ 点加号,选择Libraries,选择tomcat,添加即可找到Servlet接口

5 web.xml 开发 Servlet

① 实现步骤

创建一个 HelloServlet 实现 Servlet 接口

重写接口中的所有方法,在 service 方法中输出内容到控制台

配置 web/WEB-INF/web.xml 文件

② 创建 HelloServlet 实现 Servlet 接口

java 复制代码
// 重写所有方法,在 service 方法中往控制台输出:Hi~
public class PlayServlet 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("Hi~");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
}

③ web配置

java 复制代码
<?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">
          
<!-- 真实路径与映射路径通过name连接-->        
<!-- servlet 信息配置 真实路径-->
<servlet>
    <!--servlet 名字-->
    <servlet-name>HelloServlet</servlet-name>
    <!-- servlet类全限定名-->
    <servlet-class>com.tj.PlayServlet</servlet-class>
</servlet>
<!--servlet 访问地址配置(映射路径) -->
<servlet-mapping>
    <!--servlet 名字:与上面的名字相同 -->
    <servlet-name>HelloServlet</servlet-name>
    <!-- 浏览器访问地址,必须以/开头 -->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>

④ 部署项目后通过浏览器访问 Servlet(本地地址+项目虚拟访问路径+Servlet访问路径)

6 注解开发 Servlet

① @WebServlet 注解 -- 简化 javaweb 代码,省略 web.xml配置文件

@WebServlet注解属性 说明
name = "PlayServlet" Servlet名字,等价 < servlet-name >PlayServlet</ servlet-name>
urlPatterns = "/hello" 访问地址,等价 < url-pattern>/hello</ url-pattern>
value="/hello" 如果其它属性都不写,可以省略 value,只写访问地址即可。不能与urlPatterns同时指定

② 开发步骤

使用注解,必须是 JavaEE 6.0 版本以上,Servlet3.0 之后才可以,Tomcat8 已经实现了3.0规范

创建类实现 Servlet 接口,在类上使用 @WebServlet 注解中添加 urlPatterns="/hello"或value="/hello",作为请求路径

③ 创建 PlayServlet,实现接口所有方法,使用注解 @WebServlet 配置访问地址

java 复制代码
// 使用注解 @WebServlet 配置访问地址
@WebServlet(name = "PlayServlet",urlPatterns = "/hello")
public class PlayServlet 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("Hi~");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {}
}

④ 登录 http://localhost:8080/hello 控制台会输出Hi~

二 Servlet 的生命周期

1 名词解释

类的生命周期:创建对象--> 运行操作-->销毁操作

Servlet 对象的生命周期:Servlet 创建对象-->初始化操作--> 运行操作-->销毁操作

Web 服务器管理了 Servlet 的生命周期,Servlet 对象整个过程都是 Web 服务器来管理的。

生命周期 操作
实例化 Servlet容器Tomcat创建Servlet的实例
初始化 该容器调用init()方法,调用一次
请求处理 若请求Servlet,则容器调用service()方法,调用多次
服务终止 销毁实例之前调用destroy()方法

2 Servlet 接口中生命周期方法

生命周期方法 作用 运行次数
构造方法 在对象实例化的时候执行必须有公共的无参数构造方法 一次
void init(ServletConfig config) 初始化时执行 一次
void service(ServletRequest req, ServletResponse res) 每次请求都会执行 N次
void destroy() 在服务器正常关闭的时候 一次

3 Servlet 的请求流程

java 复制代码
localhost:8080/play/hello
1. 浏览器发送请求,Tomcat接收到请求并通过解析请求地址获取到要访问的项目和资源路径
项目访问路径:/play
资源路径: /hello
2. Tomcat服务器内部会扫描play项目下的所有Servlet:获得每一个Servlet的访问地址并存储到集合
中:
Map<String,String> map1 = new HashMap<>();
map1.put("/hello","cn.tj.servlet.PlayServlet");
3. 将资源路径 /hello 作为键从 map1 集合中获得值:得到类全限定名
4. 需要判断是否是第一次访问:
Servlet实例缓存池: Map<String, Servlet> map2 = new HashMap<>();
if(map2.get("全限定名") == null){
// 第一次访问,执行第5步
} else{
// 第N次,直接执行第7步
}
5. 通过反射实例化这个 Servlet 对象,存入实例缓存池中.
6. Tomcat 创建 ServletConfig 对象然后调用 init 方法
7. 创建 request 和 response 对象
8. 调用 service 方法,将 request和 response 对象传递进来,在 service 方法中通过
response对象返回输出到浏览器,在浏览器上显示出来。
9. 等待下一次的访问

三 Servlet 继承体系

1 继承结构

2 GenericServlet类

默认实现了 Servlet 和 ServletConfig 这两个接口,将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象。定义Servlet类继承GenericServlet时,只需实现service()方法即可。它的子类是 HttpServlet。

java 复制代码
@WebServlet(name = "Play",urlPatterns = "/play")
public class Play extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.err.println("OK");
    }
}

3 HttpServlet类

本类是对http协议的一种封装,可提前判断请求方式,针对view层传递的get,post请求复写doGet/dopost方法,简化操作。

java 复制代码
@WebServlet(name = "Play",urlPatterns = "/play")
public class Play extends HttpServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.err.println("OK");
    }
}

四 ServletConfig 对象

1 作用

用来封装 Servlet 初始化的时候的一些配置信息,与Servlet有关的配置信息,写在web.xml中,便于修改和维护。

java 复制代码
// ServletConfig接口常用方法
String getInitParameter("参数名") // 通过指定的参数名得到参数

2 使用

① 于 web.xml 中通过 init 设置属性

java 复制代码
<?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">
<!-- servlet 信息配置 -->
<servlet>
    <!--servlet 名字-->
    <servlet-name>PlayServlet</servlet-name>
    <!-- servlet类全限定名-->
    <servlet-class>com.tj.PlayServlet</servlet-class>
    <!--配置初始化参数init-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</servlet>
<!--servlet 访问地址配置 -->
<servlet-mapping>
    <!--servlet 名字:与上面的名字相同 -->
    <servlet-name>PlayServlet</servlet-name>
    <!-- 浏览器访问地址,必须以/开头 -->
    <url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>

② 通过 getInitParameter 获取属性

java 复制代码
public class PlayServlet extends HttpServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        // 父类中的方法
        ServletConfig servletConfig = this.getServletConfig();
        // 获取web.xml文件的配置信息
        String code=servletConfig.getInitParameter("encoding");
        servletRequest.setCharacterEncoding(code);
        System.out.println(code);
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {}
}

3 配置多个路径

① 一个 < servlet-mapping> 中写多个 < url-pattern>

java 复制代码
< servlet-mapping>
< servlet-name>PlayServlet< /servlet-name>
// 使用两个路径都能访问 PlayServlet
< url-pattern>/hello.html< /url-pattern>
< url-pattern>/hello1.html< /url-pattern>
< /servlet-mapping>

② 一个 < servlet> 对应多个 < servlet-mapping>

java 复制代码
// <url-pattern> 中的内容必须唯一,必须以 / 开头。
<servlet-mapping>
<servlet-name>PlayServlet</servlet-name>
<url-pattern>/hello.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PlayServlet</servlet-name>
<url-pattern>/hello1.html</url-pattern>
</servlet-mapping>

③ 注解形式

java 复制代码
@WebServlet(name = "Play",urlPatterns = {"/play","/play1"})
public class Play extends HttpServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.err.println("OK");
    }
}

4 loadOnStartup 属性

servlet在创建对象或者是初始化的时候需要执行耗时操作,导致相第一个访问的用户要等待比较长的时间。让 web 容器启动的时候创建并初始化 Servlet,这样用户体验度就会增加

① web

java 复制代码
<servlet>
    <!--servlet 名字-->
    <servlet-name>PlayServlet</servlet-name>
    <!-- servlet类全限定名-->
    <servlet-class>com.tj.PlayServlet</servlet-class>
    <!--取值范围1到10,值越小越先加载。默认值是-1:代表第1次访问时创建和初始化-->
    <load-on-startup>1</load-on-startup>
    <!--配置初始化参数init-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</servlet>

② 注解

java 复制代码
@WebServlet(name = "Play",urlPatterns = {"/play","/play1"},loadOnStartup = 1)
public class Play extends HttpServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.err.println("OK");
    }
}

5 通配符映射 *

通配符格式 说明
/* /目录名/* /* :匹配所有的访问地址,必须以 / 开头/admin/*:匹配 admin 目录下的所有地址
*.扩展名 匹配某个扩展名结尾的访问地址。如:*.action *.do

映射路径必须保证唯一性,除通配符结合扩展名使用,否则必须以 / 开头

相关推荐
李慕婉学姐1 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆3 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin3 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20053 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉4 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国4 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882484 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈5 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_995 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹5 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理