servlet 生命周期详解,servlet 运行工作原理详解

servlet 生命周期,servlet 运行工作原理

servlet 生命周期

	Servlet生命周期定义了一个Servlet如何被加载、初始化,以及它怎样接收请求、响应请求,提供服务。
    Servlet 生命周期可以归纳为:Servlet 加载--->实例化--->服务--->销毁
    每个Servlet的运行都遵循如下生命周期:
  1. 创建Servlet实例

  2. WEB容器调用Servlet的init()方法,对Servlet进行初始化

  3. Servlet初始化之后,将一直存在于容器中,service()响应客户端请求

  4. 如果客户端发送GET请求,容器调用Servlet的doGet方法处理并响应请求

  5. 如果客户端发送POST请求,容器调用Servlet的doPost方法处理并响应请求

  6. WEB容器决定销毁Servlet时,先调用Servlet的destroy()方法,通常在关闭web应用之前销毁Servlet

处理请求流程

  1. 用户点击一个链接,指向了一个servlet而不是一个静态页面。

  2. 容器“看出”这个请求是一个Servlet,所以它创建了两个对象HttpServletRequest和HttpServletResponse。

  3. 容器根据请求中的URL找到正确的Servlet,为这个请求创建或分配一个线程,并把请求和响应对象传递给这个Servlet线程。

  4. 容器调用Servlet的service()方法。根据请求的不同类型,service()方法会调用doGet()或doPost()方法。这里假设调用doGet()方法。

  5. doGet()方法生成动态页面,并把这个页面“塞到”响应对象里,需要注意的是,容器还有响应对象的一个引用!

  6. 线程结束,容器把响应对象转换为一个HTTP响应,并把它发回给客户,然后删除请求和响应对象。

servlet 运行工作原理

Servlet是一门用于开发动态web网页的技术,用于交互式地浏览和修改数据,生成动态Web内容。

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

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

3、Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,将ServletRequest和ServletResponse转变成为HttpServletRequest和HttpServletResponse在service中实现。

源码

@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {

HttpServletRequest  request;
HttpServletResponse response;

try {
    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;
} catch (ClassCastException e) {
    throw new ServletException("non-HTTP request or response");
}
service(request, response);
}

protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
    long lastModified = getLastModified(req);
    if (lastModified == -1) {
        // servlet doesn't support if-modified-since, no reason
        // to go through further expensive logic
        doGet(req, resp);
    } else {
        long ifModifiedSince;
        try {
            ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
        } catch (IllegalArgumentException iae) {
            // Invalid date header - proceed as if none was set
            ifModifiedSince = -1;
        }
        if (ifModifiedSince < (lastModified / 1000 * 1000)) {
            // If the servlet mod time is later, call doGet()
            // Round down to the nearest second for a proper compare
            // A ifModifiedSince of -1 will always be less
            maybeSetLastModified(resp, lastModified);
            doGet(req, resp);
        } else {
            resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        }
    }

} else if (method.equals(METHOD_HEAD)) {
    long lastModified = getLastModified(req);
    maybeSetLastModified(resp, lastModified);
    doHead(req, resp);

} else if (method.equals(METHOD_POST)) {
    doPost(req, resp);

} else if (method.equals(METHOD_PUT)) {
    doPut(req, resp);

} else if (method.equals(METHOD_DELETE)) {
    doDelete(req, resp);

} else if (method.equals(METHOD_OPTIONS)) {
    doOptions(req,resp);

} else if (method.equals(METHOD_TRACE)) {
    doTrace(req,resp);

} else {
    String errMsg = lStrings.getString("http.method_not_implemented");
    Object[] errArgs = new Object[1];
    errArgs[0] = method;
    errMsg = MessageFormat.format(errMsg, errArgs);

    resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
	}
}

一般来说service方法是不需要重写的,因为在HttpServlet中已经有了很好的实现,它会根据请求的方法名(GET,POST),调用doGet,doPos以及其他的doXXX方法,也就是说service是用来转向的,所以我们一般写一个servlet,只需要重写doGet或者doPost就可以了。

1.当一个客户通过HTML 表单发出一个HTTP POST请求时,doPost()方法被调用。与POST请求相关的参数作为一个单独的HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时,应该使用doPost()方法。

2.当一个客户通过HTML 表单发出一个HTTP GET请求或直接请求一个URL时,doGet()方法被调用。与GET请求相关的参数添加到URL的后面,并与这个请求一起发送。当不会修改服务器端的数据时,应该使用doGet()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值