前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Servlet3.0新特性:这些你都知道么??

Servlet3.0新特性:这些你都知道么??

作者头像
路人甲Java
发布2021-03-21 13:12:33
2.1K0
发布2021-03-21 13:12:33
举报
文章被收录于专栏:路人甲Java路人甲Java

从今天开始,我们进入 springboot 系列了。

本文是 springboot 系列第 1 篇,平常我们用 springboot 最多的场景是开发 web 项目,而 springboot 中开发 web 用的是 springmvc,而 springmvc 是依靠 servlet 建立起来的,所以我们需要先了解 servlet,servlet 比较早的版本是 2.5,然后 3.0 改动比较大,目前已经 5.0 以上的版本了,3.0 改动比较大,所以本文主要以 servlet3.0 为例,来说一下 servlet3.0 中的一些新特性。

1、依赖软件及版本

  • jdk1.8
  • maven3.6.1
  • tomcat10

2、Servlet3.0 新特性

  • 新增注解支持,通过注解的方式可以非常方便的定义 servlet、filter、listener
  • Servlet3.0 简化文件上传(@MultipartConfig)
  • Servlet3.0 对异步处理支持
  • Servlet3.0 对组件可插拔的支持(web-fragment.xml)
  • Servlet3.0 对三大组件(servlet、filter、listener)动态注册的支持

下面我们一个个来看下。

2、通过注解定义三大组件

servlet3.0 之前,定义 servlet、filter、listener,都需在 web.xml 中进行配置,而 3.0 及后面的版本中 web.xml 不是必须的了,可有可无,可以采用注解的方式来定义这些组件。

Servlet 3.0 的部署描述文件 web.xml 的顶层标签有一个 metadata-complete 属性,如下图,该属性指定当前的部署描述文件是否是完全的,如果设置为 true,就是说整个 web 的配置信息都在 web.xml 中指定,则容器在部署时将只依赖 web.xml 文件,忽略所有的注解(同时也会跳过 web-fragment.xml 的扫描,亦即禁用可插性支持,具体请看后文关于可插性支持可插性支持) 的讲解);如果不配置该属性,或者将其设置为 false,则表示启用注解支持(和可插性支持)。

下面来看下如何通过注解的方式定义三大组件。

3、@WebServlet:定义 servlet

@WebServlet 主要属性列表

属性名

类型

描述

name

String

指定 Servlet 的 name 属性,如果没有显式指定,则该 Servlet 的取值即为类的全限定名。

value

String[]

该属性等价于 urlPatterns 属性,value 和 urlPatterns 两个属性不能同时使用。

urlPatterns

String[]

指定一组 Servlet 的 URL 匹配模式

loadOnStartup

int

指定 Servlet 的加载顺序

initParams

WebInitParam[]

指定一组 Servlet 初始化参数

asyncSupported

boolean

声明 Servlet 是否支持异步操作模式,默认是 false,后面会在 servlet 异步处理的部分讲解

description

String

该 Servlet 的描述信息

displayName

String

该 Servlet 的显示名,通常配合工具使用

用法

(1)、自定义一个类,需继承jakarta.servlet.http.HttpServlet

(2)、重写service方法

(3)、类上添加@WebServlet注解来定义 servlet 的配置信息,如下,大家重点看下@WebServlet 注解的几个属性,基本上和 web.xml 中定义 Servlet 参数是一致的。

代码语言:javascript
复制
@WebServlet(
        name = "myServlet", // servlet 名称
        urlPatterns = "/myServlet", // 哪些请求会被这个servlet处理
        // value 参数同 urlPatterns,二者选其一
        loadOnStartup = 1, // 设置servlet加载属性,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载;正数的值越小,启动该servlet的优先级越高。
        initParams = {
                @WebInitParam(name = "param1", value = "value1"),
                @WebInitParam(name = "param2", value = "value2")
        }, // 定义servlet初始化参数
        asyncSupported = false // 是否支持异步
)

案例

创建一个 maven 项目,添加 servlet5.0 依赖

代码语言:javascript
复制
<dependency>
    <groupId>jakarta.servletgroupId>
    <artifactId>jakarta.servlet-apiartifactId>
    <version>5.0.0-M1version>
    <scope>providedscope>
dependency>

创建 servlet,代码如下,MyServlet 会处理/mySevlet 请求,servlet 接受到请求之后,会将当前 servlet 的初始化参数输出到客户端。

代码语言:javascript
复制
package com.javacode2018.springboot.lesson001.demo1;

import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Enumeration;

@WebServlet(
        name = "myServlet", // servlet 名称
        urlPatterns = "/myServlet", // 哪些请求会被这个servlet处理
        // value 参数同 urlPatterns,二者选其一
        loadOnStartup = 1, // 设置servlet加载属性,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载;正数的值越小,启动该servlet的优先级越高。
        initParams = {
                @WebInitParam(name = "param1", value = "value1"),
                @WebInitParam(name = "param2", value = "value2")
        }, // 定义servlet初始化参数
        asyncSupported = false // 是否支持异步
)
public class MyServlet extends HttpServlet {

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration initParameterNames = this.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String initParamName = initParameterNames.nextElement();
            String initParamValue = this.getInitParameter(initParamName);
            try {
                resp.getWriter().append(String.format("%s:%s", initParamName, initParamValue));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行程序,通常我们会将 web 项目部署到 tomcat 中,tomcat 目前已经到 10 了,每个版本支持的 servlet 不一样,对应关系如下表

代码语言:javascript
复制
tomcat版本和servlet版本对应关系:https://tomcat.apache.org/whichversion.html

Servlet Spec

JSP Spec

EL Spec

WebSocket Spec

Authentication (JASIC) Spec

Apache Tomcat Version

Latest Released Version

Supported Java Versions

5.0

3.0

4.0

2.0

2.0

10.0.x

10.0.2

8 and later

4.0

2.3

3.0

1.1

1.1

9.0.x

9.0.43

8 and later

3.1

2.3

3.0

1.1

1.1

8.5.x

8.5.63

7 and later

3.1

2.3

3.0

1.1

N/A

8.0.x (superseded)

8.0.53 (superseded)

7 and later

3.0

2.2

2.2

1.1

N/A

7.0.x

7.0.108

6 and later (7 and later for WebSocket)

2.5

2.1

2.1

N/A

N/A

6.0.x (archived)

6.0.53 (archived)

5 and later

2.4

2.0

N/A

N/A

N/A

5.5.x (archived)

5.5.36 (archived)

1.4 and later

2.3

1.2

N/A

N/A

N/A

4.1.x (archived)

4.1.40 (archived)

1.3 and later

2.2

1.1

N/A

N/A

N/A

3.3.x (archived)

3.3.2 (archived)

1.1 and later

这里我们使用最新的 tomcat10,下载地址

代码语言:javascript
复制
https://tomcat.apache.org/download-10.cgi

将案例发布到 tomcat 运行,然后访问地址http://localhost:8080/myServlet即可访问我们上面定义的 servlet,输出如下图

4、@WebFilter:定义 Filter

@WebFilter 的常用属性

属性名

类型

描述

filterName

String

指定过滤器的 name 属性

value

String[]

该属性等价于 urlPatterns 属性,value 和 urlPatterns 两个属性不能同时使用。

urlPatterns

String[]

指定一组过滤器的 URL 匹配模式

servletNames

String[]

指定过滤器将应用于哪些 Servlet,取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 的取值。

dispatcherTypes

DispatcherType

指定过滤器的转发模式,具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。

initParams

WebInitParam[]

指定一组过滤器初始化参数,等价于 标签。

asyncSupported

boolean

声明过滤器是否支持异步操作模式

description

String

该过滤器的描述信息

displayName

String

该过滤器的显示名,通常配合工具使用

dispatcherTypes 参数有 4 个值

说明

REQUEST

默认值,通过前端发送过来的请求会被拦截

FOWARD

通过 forward 转发过来的请求会被拦截

INCLUDE

通过 include 过来的请求会被拦截

ERROR

这个可能开发者不是很熟悉,意思是当触发了一次 error 的时候,就会走一次指定的过滤器

ASYNC

会拦截异步的请求,这个以后会在讲 servlet 异步的时候会说。

用法详解

(1)、自定义一个类,需继承jakarta.servlet.http.HttpFilter

(2)、重写doFilter方法,注意是 protected 的 doFilter 方法,如下

代码语言:javascript
复制
@Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
    super.doFilter(req, res, chain);
}

(3)、类上添加@WebFilter注解来定义 Filter 的配置信息,如下,大家重点看下@WebFilter 的几个属性,基本上和 web.xml 中定义 Filter 参数是一致的

代码语言:javascript
复制
@WebFilter(
        filterName = "myFilter", // filter名称
        urlPatterns = "/*", //拦截的地址
        servletNames = "myServlet", //拦截的servlet名称列表
        dispatcherTypes = {DispatcherType.REQUEST},//拦截的请求类型
        initParams = {@WebInitParam(name = "p1", value = "v1")}, //定义Filter初始化参数列表
        asyncSupported = false // 是否支持异步
)

案例

代码语言:javascript
复制
package com.javacode2018.springboot.lesson001.demo1;

import jakarta.servlet.DispatcherType;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

@WebFilter(
        filterName = "myFilter", // filter名称
        urlPatterns = "/*", //拦截的地址
        servletNames = "myServlet", //拦截的servlet名称列表
        dispatcherTypes = {DispatcherType.REQUEST},//拦截的请求类型
        initParams = {@WebInitParam(name = "p1", value = "v1")}, //定义Filter初始化参数列表
        asyncSupported = false // 是否支持异步
)
public class MyFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println(req.getRequestURL()); // 输出请求的地址
        super.doFilter(req, res, chain);
    }
}

**Filter 会拦截哪些请求呢?**urlPatterns、servletNames、dispatcherTypes 都匹配的请求才会被拦截

案例发布到 tomcat,浏览器中访问http://localhost:8080/myServlet,控制台输出

5、@WebListener:定义监听器

@WebListener 的常用属性

属性名

类型

是否可选

描述

value

String

该监听器的描述信息。

用法

(1)、自定义一个类,实现下面任意一个监听器接口

监听器类

说明

ServletContextListener

监听 servlet 上下文的创建和销毁,web 容器启动和销毁的时候会被调用

ServletContextAttributeListener

监听 ServletContext 中属性变化

HttpSessionListener

监听 session 的创建和销毁

HttpSessionActivationListener

Activate 与 Passivate 是用于置换对象的动作,当 session 对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透 过对象序列化),所作的动作称之为 Passivate,而硬盘或储存器上的 session 对象重新加载 JVM 时所采的动作称之为 Activate,所以容 易理解的,sessionDidActivate()与 sessionWillPassivate()分别于 Activeate 后与将 Passivate 前呼叫。

HttpSessionAttributeListener

session 中添加值或者移除值的时候会被调用

HttpSessionBindingListener

实现了 HttpSessionBindingListener 的类,在和 session 绑定、解除绑定时触发其事件

ServletRequestListener

监听 request 的创建和销毁

ServletRequestAttributeListener

requet 中添加值和删除值的时候会被调用

(2)类上添加@WebListener 注解

代码语言:javascript
复制
@WebListener("自定义的ServletContextListener")

案例

下面我们自定义一个 ServletContextListener,用来监听容器的启动和销毁,代码如下

代码语言:javascript
复制
package com.javacode2018.springboot.lesson001.demo1;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;

/**
 * 通过 @WebListener 注解定义监听器
 */
@WebListener("自定义的ServletContextListener")
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println(this.getClass().getName() + ",监听servlet容器的启动!!!!!");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println(this.getClass().getName() + ",监听servlet容器的销毁!!!!!");
    }
}

启动 tomcat,然后再停止 tomcat,控制台输出

下一篇继续介绍 servlet3.0 的其他部分。

接下来介绍 2 个功能,比较适合小白

  • 使用 idea 如何创建 web 项目
  • 如何在 idea 中配置 tomcat

下面我们来看看。

6、使用 idea 创建 web 项目

step1、先安装 maven

如果对 maven 不熟悉的可以先去看我的maven系列,springboot 系列每篇中都会用到 maven。

这里我们使用 maven3.6.1,请大家也安装这个版本,环境咱们保持一致,这样运行的过程中,才能确保结果是一致,避免走一些不必要的弯路。

maven3.6.1 下载地址:

代码语言:javascript
复制
https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz

maven 版本列表地址:

代码语言:javascript
复制
https://archive.apache.org/dist/maven/maven-3/

step2、idea 中配置 maven

File->Settings->Maven

step3:创建 web 项目

File->New->Project->Maven,勾选Create from archetype,选择maven-archetype-webapp,如下,这样一个 web 项目就创建好了。

7、idea 中配置 tomcat

step1、下载 tomcat

这里我们下载 tomcat10,下载地址,大家根据自己的机器选择需要下载的包,我的机器是 window 64 位的,所以下载的是 64-bit windows.zip

代码语言:javascript
复制
https://tomcat.apache.org/download-10.cgi

step2、解压下载的 tomcat 包

解压之后,tomcat 目录结构如下,大家复制这个目录的地址,这就是 tomcat 的 home 目录地址,稍后在 idea 中配置的时候需要用到

step3、idea 中配置 tomcat

我们把案例中的项目发布到 tomcat

step4、将 tomcat 添加到 server 列表中

需要先在 view 中找到 services,点击之后打开 services 列表窗口,然后在列表窗口中将 tomcat 添加到 services 列表中,具体操作过程如下:

8、源码

代码语言:javascript
复制
https://gitee.com/javacode2018/springboot-series

9、更多好文章

  1. Spring 系列(共 56 篇)
  2. Java 高并发系列(共 34 篇)
  3. MySql 高手系列(共 27 篇)
  4. Maven 高手系列(共 10 篇)
  5. Mybatis 系列(共 12 篇)
  6. 聊聊 db 和缓存一致性常见的实现方式
  7. 接口幂等性这么重要,它是什么?怎么实现?
  8. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 路人甲Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、依赖软件及版本
  • 2、Servlet3.0 新特性
  • 2、通过注解定义三大组件
  • 3、@WebServlet:定义 servlet
    • @WebServlet 主要属性列表
      • 用法
        • 案例
        • 4、@WebFilter:定义 Filter
          • @WebFilter 的常用属性
            • 用法详解
              • 案例
              • 5、@WebListener:定义监听器
                • @WebListener 的常用属性
                  • 用法
                    • 案例
                    • 6、使用 idea 创建 web 项目
                      • step1、先安装 maven
                        • step2、idea 中配置 maven
                          • step3:创建 web 项目
                          • 7、idea 中配置 tomcat
                            • step1、下载 tomcat
                              • step2、解压下载的 tomcat 包
                                • step3、idea 中配置 tomcat
                                  • step4、将 tomcat 添加到 server 列表中
                                  • 8、源码
                                  • 9、更多好文章
                                  相关产品与服务
                                  容器服务
                                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档