Servlet(二)
Servlet的生命周期
Servlet生命周期概述与方法
生命周期指一个对象从创建到销毁的过程
- 出生:(初始化)用户第一次访问时执行。
- 活着:(服务)应用活着,每次访问都会执行。
- 死亡:(销毁)应用卸载。
- servlet生命周期方法:
- init(ServletConfig config)
- service(ServletRequest req, ServletResponse res)
- destroy()
Servlet生命周期描述
-
基础
- 默认情况下,来了第一次请求,会调用init()方法进行初始化【调用一次】
- 任何一次请求都会调用service()方法处理这个请求
- 服务器正常关闭或者项目从服务器移除,调用destory()方法进行销毁【调用一次】
-
扩展
- servlet是单例多线程的,尽量不要在servlet里面使用全局(成员)变量,可能会导致线程不安全
- 单例:只有一个对象【init()调用一次,创建一次】
- 多线程:服务器会针对每次请求,开启一个线程调用service()方法处理这个请求
ServletConfig
Servlet的配置对象,可以使用ServletConfig来获得Servlet的初始化参数,在SpringMVC里面会遇到
-
先在配置文件里面配置初始化参数
<?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_3_1.xsd" version="3.1"> <!--配置Servlet--> <servlet> <!--servlet-name: 名字 随便取; 一般就是类名--> <servlet-name>ServletDemo01</servlet-name> <!--servlet-class:Servlet这个类的全限定名--> <servlet-class>test01.ServletDemo01</servlet-class> <!--配置初始化参数,为键值对的方式--> <init-param> <param-name>key01</param-name> <param-value>value222</param-value> </init-param> </servlet> <servlet-mapping> <!--servlet-name: 必须和servlet标签里面的servlet-name一样--> <servlet-name>ServletDemo01</servlet-name> <!--url-pattern: 配置访问的路径--> <url-pattern>/demo01</url-pattern> </servlet-mapping> </web-app>
-
可以通过
key01
获得value222
package test01; import javax.servlet.*; import java.io.IOException; public class ServletDemo01 implements Servlet { @Override //服务方法: 处理请求 public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println("hello world..."); } //使用ServletConfig来获得Servlet的初始化参数 @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("init()方法获得键key01的值为:" + servletConfig.getInitParameter("key01")); } @Override public ServletConfig getServletConfig() { return null; } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
-
发布项目,浏览器跳转到welcome页面,此时我们访问
/demo01
路径,可以看到控制台输出了:init()方法获得键key01的值为:value222
hello world...
注意:可以看到先执行了init()方法,因为第一次请求,会调用init()方法进行初始化,然后每一次请求都会调用service()方法处理,所以先执行了init()方法,然后执行了service()方法。
启动项
Servlet默认情况下是第一次请求的时候创建,如果想让Servlet提前创建(服务器启动的时候),这个时候就可以使用启动项,在SpringMVC里面会用到。
<!--启动项,值越小,优先级越高-->
<load-on-startup>1</load-on-startup>
Servlet体系结构
-
Servlet接口
在 Servlet(一)中已经创建了一个类以实现Sevlet接口的方式开发Servlet程序,实现Servlet接口的时候必须实现接口的所有方法。但是在servlet中,真正执行程序逻辑的是service,对于servlet的初始化和销毁,由服务器调用执行,开发者本身不需要关心。因此,需要一种更加简洁的方式来开发servlet程序。
-
查阅API回顾Servlet接口:
由上图可知在servlet接口规范下,官方推荐使用继承的方式,继承GenericServlet或者HttpServlet来实现接口
-
接下来再查阅这两个类的API:
-
GenericServlet类
阅读上图API可知,GenericServlet是一个类,它简化了servlet的开发,已经提供好了一些servlet接口所需的方法,开发者只需重写service方法即可
-
使用GenericServlet创建servlet:
-
创建一个类
-
继承GenericServlet
-
重写service方法
package test03; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebServlet; import java.io.IOException; @WebServlet(name = "GenericDemoServlet",urlPatterns = "/generic") public class GenericDemoServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("GenericDemoServlet执行..."); } }
-
发布项目,在浏览器访问【http://localhost:8080/Generic_war_exploded/generic】时,控制台输出
GenericDemoServlet执行...
-
-
HttpServlet
虽然GenericServlet已经简化了servlet开发,但是日常开发程序需要按照一种互联网传输数据的协议来开发程序—http协议,因此,sun公司又专门提供了HttpServlet,来适配这种协议下的开发。
阅读上图的API可知,继承HttpServlet,我们只需要重写doGet、doPost等方法中一个即可,根据Http不同的请求,我们需要实现相应的方法。
-
使用HttpServlet创建servlet:
-
创建一个类
-
继承HttpServlet
-
重写doGet方法和doPost方法
package test04; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Servlet的常用的编写方法: * 1. 写一个类继承HttpServlet,重写doGet和doPost方法 * 1.1 doGet()方法,是处理来自客户端的get请求 * 1.2 doPost()方法,是处理来自客户端的post请求 * * 通常情况下:服务器端针对同一个请求(不同的请求方式)不会做不同的处理,所以我们会选择在doGet中调用doPost * 2. 配置servlet的映射路径 */ @WebServlet("/http") public class HttpDemoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("处理收到的post请求..."); } }
-
使用Postman发送一个post请求
-
可以看到控制台输出了
处理收到的post请求...
通过以上两个API注意一个细节:HttpServlet是GenericServlet的子类,它增强了GenericServlet一些功能,因此,在后期使用的时候,都是选择继承HttpServlet来开发servlet程序。
-
-
-
继承关系:
-
可以直接创建一个类继承HttpServlet,直接在IDEA里面new Servlet
评论区