Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 初始化后调用 init () 方法。

  • Servlet 调用 service() 方法来处理客户端的请求。

  • Servlet 销毁前调用 destroy() 方法。

  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

    执行原理

    步骤:

    1. Web Client 向Servlet容器(Tomcat)发出Http请求

    2. Servlet容器接收Web Client的请求

    3. Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。

    4. Servlet容器创建一个HttpResponse对象

    5. Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet 对象。

    6. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。

    7. HttpServlet调用HttpResponse对象的有关方法,生成响应数据。

    8. Servlet容器把HttpServlet的响应结果传给Web Client。

    原理:

    • 首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet()、doPost()等等这些方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。

    • 每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。

    • Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。

    init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

init 方法的定义如下:

public void init() throws ServletException {
  // 初始化代码...
}

service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

利用service()方法代替doGet()方法和doPost()方法,反射。

 @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String method=req.getParameter("method");
        try {
            this.getClass().getDeclaredMethod(method,HttpServletRequest.class,HttpServletResponse.class).invoke(this,req,resp);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征

doGet() 方法

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}

doPost() 方法

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收,即销毁方法。

 public void destroy() {
    // 终止化代码...
  }

过滤器(Filter)的简介

过滤器的作用: 过滤器可以对所有的请求或者响应做拦截操作.

1:以常规的方式调用资源(Servlet/JSP);

2:利用修改过的请求信息调用资源;

3:调用资源之后,但在响应到客户端之前,对响应做出修改;

4:阻止当前资源调用,代之转到其他资源.

Filter的开发和使用

1:自定义一个类(XxxFilter,Xxx表示功能名),实现于javax.servlet.Filter接口.

2:在wed.xml里面配置拦截器

 
<filter>          
 
<filter-name>XxxFilter</filter-name>         
 
  <filter-class>XxxFilter类的全限定名</filter-class>
 
</filter>     
 
 <filter-mapping>          
 
<filter-name>XxxFilter</filter-name>          
 
<!--表示:当前Filter只对哪些资源做过滤/拦截操作,只对hello.jsp做拦截-->          
 
<url-pattern>/hello.jsp</url-pattern>      
 
</filter-mapping>

Filter的生命周期方法

void init(FilterConfig config): 初始化方法 
 
(2):void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):执行过滤的方法(每一次请求都会执行过滤) 
 
(3):void destroy():销毁方法 执行的流程:   在启动Tomcat服务器的时候,就会执行构造器和init方法.     构造器--->init方法   -----> (  doFilter方法  )N次------->destroy方法

  1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行

  2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行

  3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行

  4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行

监听器分类

1.按监听对象分类

(1)用于监听应用程序对象(ServletContext)

(2)用于监听用户会话对象(HttpSession)

(3)用于监听请求消息对象(ServletRequest)

2.按监听事件分类

(1)监听对象的创建和销毁的事件监听器。

(2)监听对象属性变更(添加、修改、删除)的监听器。

监听器接口

Servlet API中定义了监听器接口,用来监听不同的事件类型。

ServletContextListener:上下文监听器;
ServletContextAttribute:上下文属性监听器;
ServletRequestListener:请求监听器;
ServletRequestAttributeListener:请求属性监听器;
HttpSessionListener:会话监听器;
HttpSessionAttribute:会话属性监听器.

配置监听器类:

创建监听器类,实现监听器接口,在web.xml文件中配置监听器类。

<listener>
    <listener-class>监听器类全类名</listener-class>
</listener>

实例

监听器类(java代码)

<br class="Apple-interchange-newline"><div></div>

 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
public class ObjectListener implements ServletContextListener, ServletRequestListener {
    /*
    监听ServletContext对象的创建
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext创建了");
        ServletContext application = sce.getServletContext();//整个应用程序只有一个对象
        application.setAttribute("config","123");//设置初始化数据
    }
    /*
    监听ServletContext对象的销毁
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext销毁了");
    }
    /*
   请求对象创建
    */
    long s = 0;
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("请求对象创建");
        s = System.currentTimeMillis();
    }
    /*
    请求对象销毁
     */
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("请求对象销毁");
        //获取客户端ip
        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
        System.out.println(request.getRemoteAddr()+"请求耗时:::"+(System.currentTimeMillis()-s));
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值