20200421——Servlet

什么是Servlet

Java Servlet是运行在web服务器或应用服务器上的程序,它是作为Web浏览器或者是其他的Http客户端的请求和Http服务器上的数据库或应用程序之间的中间件。

Servlet的工作模式

一开始,客户端发送请求给服务器
服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器。
服务器将响应返回客户端。

Servlet工作原理以及流程
Servlet接口定义了Servlet与Servlet容器之间的契约,(Servlet容器例如Tomcat)。Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它的具体方法。

用户请求致使Servlet容器调用Servlet的Service()方法,并传入一个ServletRequest对象和一个ServletResponse对象。ServletRequest对象和ServletResponse对象都是由Servlet容器(例如TomCat)封装好的,并不需要程序员去实现,程序员可以直接使用这两个对象。

ServletRequest中封装了当前的Http请求,因此,开发人员不必解析和操作原始的Http数据。ServletResponse表示当前用户的Http响应,程序员只需直接操作ServletResponse对象就能把响应轻松的发回给用户。

Servlet接口中定义的方法

第一次在idea中使用Servlet的话是调用不了,java没有引入这个jar包
在这里插入图片描述
需要在Project Structure中引入

新建一个MyFirstServlet的一个类
在这里插入图片描述
在这里插入图片描述
查看一下源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.servlet;

import java.io.IOException;

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}

init
service
destroy

servlet的生命周期
其中,init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。Servlet容器(例如TomCat)会根据下面的规则来调用这三个方法:

1.init( ),当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,就像人只能“出生”一次一样。我们可以利用init( )方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化

2.service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。就像人一样,需要不停的接受老板的指令并且“工作”。第一次请求时,在这里插入代码片Servlet容器会先调用init()方法初始化一个Servlet对象出来,然后会调用它的service()方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。

3.destory,当要销毁Servlet时,Servlet容器就会调用这个方法,就如人一样,到时期了就得死亡。在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。

重写MyFirstServlet方法

import javax.servlet.*;
import java.io.IOException;

/**
 * @Classname MyFirstServlet
 * @Description TODO
 * @Date 2020/4/21 20:40
 * @Created by mmz
 */
public class MyFirstServlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Servlet正在被初始化");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet正在调用服务");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("数据库正在被销毁");
    }
}



**GenericServlet抽象类 **

前面我们一直继承Servlet这个接口来完成编写,但是这种方法,我们必须要实现Servlet接口中定义的所有方法,即使有一些方法中没有任何想要去实现的东西。

GenericServlet抽象类的出现很好的解决了这个问题

在这里插入图片描述
HttpServlet
HttpServlet是由GenericServlet抽象类扩展而来的。
在这里插入图片描述
里面我们可以看到两个类HttpServletRequest和HttpServletResponse,这两个类都是继承与ServletRequest与ServletResponse

在这里插入图片描述

HttpServlet的service方法

在这里插入图片描述

看图我们可知,HttpServelt,将传递过来的ServletResponse/Request对象转换成为了HttpServletRequest/Response对象,然后再调用自己的service方法
在这里插入图片描述

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

我们可以仔细的看一下代码的逻辑
相当于解析了HttpServletRequest中的方法参数,用method.equals在去调用下面的doGet/doPost等等方法
这样我们只需要对doGet与doPost方法进行重写覆盖即可。

HttpServletRequest接口
在这里插入图片描述
图没有截全,主要是HttpServletRequest通过这些函数来解析这个http请求到底是来做什么的。

HttpServletResponse接口

在这里插入图片描述
是如何发送回去reponse,也是通过这些函数来进行返回的。

Response的工作流程
在这里插入图片描述
Servlet的工作流程
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值