JavaWeb中 servlet注解和生命周期 与 ServletConfig接口


世间本无易事,想要偷懒的人多了,于是就有了捷径

正如:世上本无路,走的人多了,就成了路


 ——Lungcen

目录

Servlet注解

@WebServlet注解(Servlet注解)

@WebServlet 注解的属性

 load-on-startup元素

 @WebServlet 注解的使用

注意事项

@WebServlet 注解 和 web.xml 的优缺点

Servlet生命周期

初始化阶段

加载和实例化

 调用 init() 方法进行初始化

运行时阶段

销毁阶段

生命周期执行流程

 Servlet虚拟路径的映射

单一映射 

多重映射

虚拟路径匹配规则

完全路径匹配

 目录匹配

扩展名匹配

缺省匹配(默认匹配)

 ServletConfig接口

获得 ServletConfig 对象

ServletConfig 接口提供的方法



Servlet注解


@WebServlet注解(Servlet注解)

在 Servlet 中,web.xml 扮演的角色十分的重要,它可以将所有的 Servlet 的配置集中进行管理, 但是若项目中 Servelt 数量较多时,web.xml 的配置会变得十分的冗长。

所以为了简化 Servlet 的配置,Servlet 3.0 中增加了注解支持

@WebServlet 注解的属性

@WebServlet 用于将一个类声明为 Servlet,该注解会在部署时被容器处理,容器根据其具体的属 性配置将相应的类部署为Servlet。

name ---> <servlet-name>
value ---> <url-pattern>
urlPatterns ---> <url-pattern>
loadOnStartup ---> <laod-on-startup>
name String 指定 Servlet 的 name 属性。 如果没有 显式指定,则取值为该 Servlet 的完全限 定名,即包名+类名。
value String[] 该属性等价于 urlPatterns 属性,两者不 能同时指定。 如果同时指定,通常是忽 略 value 的取值。
urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式。
loadOnStartup int 指定 Servlet 的加载顺序。
initParams WebInitParam[] 指定一组 Servlet 初始化参数
asyncSupported boolean 声明 Servlet 是否支持异步操作模式。
description String 指定该 Servlet 的描述信息。
displayName String 指定该 Servlet 的显示名。

 load-on-startup元素

load-on-startup 是用来标记 Servlet 容器启动时是否初始化当前 Servlet,以及当前 Servlet 的初始化顺序。

元素取值规则: 它的取值必须是一个整数; 

(懒加载)当值小于0或者没有指定时,则表示容器在该 Servlet 被首次请求时才会被加载

(饿加载)当值大于0或等于0时,表示容器在启动时加载并初始化该 Servlet

                取值越小,优先级越高;

                当取值相同时,容器就会自行选择顺序进行加载。

 @WebServlet 注解的使用

 web.xml 的顶层标签 中有一个属性:metadata-complete,该属性用于指定当前 web.xml 是否 是完全的。若该属性设置为 true,则容器在部署时将只依赖 web.xml,忽略所有的注解。若不配置该 属性,或者将其设置为 false,则表示启用注解支持。

由于 metadata-complete 属性的默认值是 false,即默认启用 Servlet 注解支持,所以默认情况 下,使用该注解时,不必创建 web.xml 文件。

@WebServlet(urlPatterns = "/Lun1.do")

@WebServlet(urlPatterns = "/Lun1.do")

这个注释等价于下面这个XMl配置文件 

<servlet>
        <servlet-name>myServlet03</servlet-name>
        <servlet-class>com.zpark.servlet.MyServlet03</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>myServlet03</servlet-name>
        <url-pattern>/Lun1.do</url-pattern>
    </servlet-mapping>

很大很大的分割线


@WebServlet(
        urlPatterns = "/Lun1.do",
        initParams = {@WebInitParam(name = "name", value = "Lungcen"),
                @WebInitParam(name = "pass", value = "110120130")
        }
        )

 @WebServlet(
        urlPatterns = "/Lun1.do",
        initParams = {@WebInitParam(name = "name", value = "Lungcen"),
                @WebInitParam(name = "pass", value = "110120130")
        }
        )

这个注释等价于下面这个XMl配置文件 

        <servlet>
            <servlet-name>myServlet03</servlet-name>
            <servlet-class>com.zpark.servlet.MyServlet03</servlet-class>
        </servlet>

        <servlet-mapping>
            <servlet-name>myServlet03</servlet-name>
            <url-pattern>/Lun1.do</url-pattern>
        </servlet-mapping>

        <init-param>
            <param-name>name</param-name>
            <param-value>Lungcen</param-value>
        </init-param>

        <init-param>
            <param-name>pass</param-name>
            <param-value>110120130</param-value>
        </init-param>

注意事项

 通过实现 Serlvet 接口或继承 GenericServlet 创建的 Servlet 类无法使用 @WebServlet 注解。

使用 @WebServlet 注解配置的 Servlet 类,不要在 web.xml 文件中再次配置该 Servlet 相关属 性。若同时使用 web.xml 与 @WebServlet 配置同一 Servlet 类,则 web.xml 中 的值与注解中 name 取值不能相同,否则容器会忽略注解中的配置。

@WebServlet 注解 和 web.xml 的优缺点

@WebServlet 注解配置 Servlet

优点:@WebServlet 直接在 Servlet 类中使用,代码量少,配置简单。

           每个类只关注自身业务逻 辑,与其他 Servlet 类互不干扰,适合多人同时开发。

缺点:Servlet 较多时,每个 Servlet 的配置分布在各自的类中,不便于查找和修改。

web.xml 配置文件配置 Servlet

优点:集中管理 Servlet 的配置,便于查找和修改。

缺点:代码较繁琐,可读性不强,不易于理解。


Servlet生命周期


生命周期是指事物从创建到毁灭的过程。人的生命周期就是从出生到死亡的过程,在这个过程中, 必定会有一些与生命周期息息相关的事件,这些事件会在生命周期中 的某个特定时刻发生。

Servlet 也有生命周期,Servlet 的生命周期就是 Servlet 从创建到销毁的过程。

Servlet 的生命周期 由 Servlet 容器管理,主要分为以下 3 个阶段:

                初始化阶段

                运行时阶段

                销毁阶段

在 javax.servlet.Servlet 接口中定义了 3 个方法:init()、service()、destory(),它们分别在 Servlet 生命周期的不同阶段被 Servlet 容器调用。

初始化阶段

Servlet 初始化是其生命周期的第一个阶段,也是其他阶段的基础。只有完成了初始化,Servlet 才 能处理来自客户端的请求。

Servlet 初始化阶段分为 2 步:1、 加载和实例化 Servlet。 2、调用 init() 方法进行初始化

加载和实例化

Servlet Servlet 容器负责加载和实例化 Servlet。当容器启动或首次请求某个 Servlet 时,容器会读取 web.xml 或 @WebServlet 中的配置信息,对指定的 Servlet 进行加载。加载成功后,容器会通过反射对 Servlet 进行实例化。

因为 Servlet 容器是通过 Java 的反射 API 来创建 Servlet 实例的,需要调用 Servlet 的默认构造方法(default constructor,即不带参数的构造方法),所以在编写 Servlet 类时,不能只提供一个带参数的构造方法。

 调用 init() 方法进行初始化

加载和实例化完成后,Servlet 容器调用 init() 方法初始化 Servlet 实例。

初始化的目的:让 Servlet 实例在处理请求之前完成一些初始化工作,例如建立数据库连接,获取配置信息等。在 Servlet 的整个生命周期内,init() 方法只能被调用一次。

初始化期间,Servlet 实例可以通过 ServletConfig 对象获取在 web.xml 或者 @WebServlet 中配置的初始化参数。

运行时阶段

运行时阶段是 Servlet 生命周期中最重要的阶段。

Servlet 容器接收到来自客户端请求时,容器会针对该请求分别创建一个ServletRequst 对象和 ServletResponse 对象,将它们以参数的形式传入 service() 方法内,并调用该方法对请求进行处理。

这里需要注意的是,执行 service() 方法前,init() 方法必须已成功执行。

在 service() 方法中, Servlet 通过 ServletRequst 对象获取客户端的相关信息和请求信息。在请求处理完成后,通过 ServletResponse 对象将响应信息进行包装,返回给客户端。当 Servlet 容器将响应信息返回给客户端 后,ServletRequst 对象与 ServletResponse 对象就会被销毁。

在 Servlet 的整个生命周期内,对于 Servlet 的每一次请求,Servlet 容器都会调用一次 service() 方 法,并创建新的 ServletRequest 和 ServletResponse 对象。即 service() 方法在 Servlet 的整个生命周 期中会被调用多次。

销毁阶段

当Servlet 容器关闭、重启或移除 Servlet 实例时,容器就会调用 destory() 方法,释放该实例使用 的资源,例如:关闭数据库连接,关闭文件的输入流和输出流等,随后该实例被 Java 的垃圾收集器所回收。

对于每个Servlet 实例来说,destory() 方法只能被调用一次。

生命周期执行流程

1、浏览器向Servlet容器发送HTTP请求

2、Servlet容器自己进行解析请求

3、解析请求后,Servlet就创建一个Servlet实例

4、Servlet容器调用Servlet的init()方法

5、Servlet容器调用Servlet的servlet()方法

6、已经实例化的Serclet向Servlet容器输出响应信息

7、Servlet容器调用Servlet的destory()方法

8、Servlet容器再向浏览器返回响应信息

在 Servlet 的整个生命周期中,创建 Servlet 实例、init() 方法和 destory() 方法都只执行一次。每次收到请求的时候,Servlet都会运行一次自己  

 Servlet虚拟路径的映射

上面我们知道用注释@WebServlet 注解配置 Servlet 。urlpatterns和value都可以指定一个Servlet的URl的访问路径(也叫映射)

单一映射 

@WebServlet(urlPatterns = "/Lun1.do")

多重映射

@WebServlet(
        urlPatterns = {"/Lun1.do", "/Lun2.do"}
        )

虚拟路径匹配规则

Servlet 虚拟路径匹配规则有以下 4 种:

1. 完全路径匹配(开发最常用的一种反式)

2. 目录匹配

3. 扩展名匹配

4. 缺省匹配(默认匹配)

完全路径匹配

又称为(精确匹配):以/开头,不能含有通配符*,必须是一个完全的路径

<!-- 完全路径匹配 -->
<servlet-mapping>
<servlet-name>MyServlet1</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

 目录匹配

以/ 字符开头,并以 /* 结 尾的字符串,常用于路径匹配

<!-- 目录匹配 -->
<servlet-mapping>
<servlet-name>MyServlet2</servlet-name>
<url-pattern>/abc/my/*</url-pattern>
</servlet-mapping>


<!-- 目录匹配 -->
<servlet-mapping>
<servlet-name>MyServlet3</servlet-name>
<url-pattern>/abc/*</url-pattern>
</servlet-mapping>

扩展名匹配

以通配符 *. 开头的字符 串,常用于扩展名匹配

<!-- 扩展名匹配 -->
<servlet-mapping>
<servlet-name>MyServlet4</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

缺省匹配(默认匹配)

映射路径为 / ,表示这个 Servlet 为当前应用的缺省 Servlet 或默认 Servlet

<!--缺省匹配 -->
<servlet-mapping>
<servlet-name>MyServlet5</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

/myservlet/*.do

这个是一个很严重的逻辑错误,虽然在我们的想法中逻辑没问题,但是*是通配符,顾名思义可以代表前面,所以这个逻辑是冲突的!

若你要要访问项目的静态资源和图片,需要将缺省匹配给删掉,不然会找不到对应的资源


 ServletConfig接口


Servlet 容器初始化 Servlet 时,会为这个 Servlet 创建一个 ServletConfig 对象,并将 ServletConfig 对象作为参数传递给 Servlet 。

通过 ServletConfig 对象即可获得当前 Servlet 的初始化参数信息。一个 Servlet 只能对应一个 ServletConfig 对 象,即 Servlet 的初始化参数仅对当前 Servlet 有效。

获得 ServletConfig 对象

1)直接从带参的 init() 方法中提取

@Override
public void init(ServletConfig config) throws ServletException {
//从带参init方法中,提取ServletConfig对象
this.servletConfig = config;
}

2)调用 GenericServlet 提供的 getServletConfig() 方法获得

//调用 GenericServlet 提供的 getServletConfig 方法获得 ServletConfig 对象
ServletConfig servletConfig = this.getServletConfig();

ServletConfig 接口提供的方法

String getInitParameter(String name) 根据初始化参数名 name,返回对应的初始化 参数值。
Enumeration getInitParameterNames() 返回 Servlet 所有的初始化参数名的枚举集合,如果该 Servlet 没有初始化参数,则返回 一个空的集合。
ServletContext getServletContext() 返回一个代表当前 Web 应用的 ServletContext 对象。
String getServletName() 返回 Servlet 的名字,即 web.xml 中 元素的 值。

世间本无易事,想要偷懒的人多了,于是就有了捷径

正如:世上本无路,走的人多了,就成了路


 ——Lungcen

猜你喜欢

转载自blog.csdn.net/qq_64552181/article/details/129762636
今日推荐