Servlet、GenericServlet、HttpServlet的区别与联系?

HttpServlet、GenericServlet、Servlet 是 Java Web 开发中的三个核心组件,它们之间的区别与联系如下:

1.区别

  • Servlet 是一个接口,提供了处理 HTTP 请求和响应的方法,使用Servlet的话,我们必须重写init()、service()、getServletConfig()、getServletInfo()、destroy()五个方法;
  • GenericServlet 是一个抽象类,实现了 Servlet 接口,并提供了一些通用的方法,比如 init()、destroy() 等,我们只需要重写service()方法;
  • HttpServlet 是一个抽象类,继承自 GenericServlet 类,提供了处理 HTTP 请求和响应的方法,并且扩展了服务的方法,比如 doGet()、doPost() 等。

2.联系

  • HttpServlet 继承自 GenericServlet,因此 HttpServlet 具备了 GenericServlet 的所有特性;
  • HttpServlet 实现了 Servlet 接口,因此 HttpServlet 具备了 Servlet 的所有方法;
  • Servlet 只是一个接口,没有实现任何方法,因此需要通过 GenericServlet 或 HttpServlet 类来实现具体的业务逻辑。

总的来说,Servlet 接口定义了处理 HTTP 请求和响应的方法,GenericServlet 类提供了通用的方法和生命周期方法,HttpServlet 类在 GenericServlet 基础上扩展了处理 HTTP 请求和响应的方法,使得开发者更加方便地处理 HTTP 请求和响应。开发者在实际开发中,通常会直接继承 HttpServlet 类,并重写其中的 doGet()、doPost() 等方法,以实现具体的业务逻辑。

知识补充:

1.Servlet规范是什么?

Servlet 规范是由 Java Community Process (JCP)制定的一组规范,用于定义 Web 应用程序开发中 Servlet API 的规则、标准和约定。Servlet 规范包括以下几个方面的内容:

  1. Servlet 接口:定义了 Servlet 的核心接口,以及 Servlet 生命周期方法。

  2. Servlet 容器:定义了 Servlet 容器的规范,包括 Servlet 容器的生命周期、管理 Servlet 的方式、加载 Servlet 类、处理请求和响应等方面。

  3. Servlet API:定义了 Servlet API,包括 ServletRequest、ServletResponse、HttpServletRequest、HttpServletResponse 等一系列类和接口。

  4. 部署描述符:定义了 web.xml 部署描述符的规范,这个描述符用于描述 Web 应用程序的部署信息,比如 Servlet 的映射、过滤器、监听器等。

Servlet 规范为 Java Web 应用程序开发提供了一套标准的开发规范和接口,使得不同厂商的 Servlet 容器和开发工具能够实现互操作性,同时也方便了开发者进行跨平台的 Web 应用程序开发。常见的 Servlet 容器包括 Tomcat、Jetty、WebLogic 等。

2.Servlet中的核心接口有什么?

Servlet 规范中定义了两个核心接口:Servlet 和 ServletContext。

  1. Servlet 接口是 Servlet API 的核心接口,所有 Servlet 类都必须实现该接口。Servlet 接口定义了一些方法,用于处理来自客户端的请求和生成响应。常用的方法包括:init()、service()、destroy() 等。

  2. ServletContext 接口表示一个 Servlet 容器的上下文,其中包含了一些 Servlet 上下文范围内的全局信息,比如 ServletContext 的初始化参数、全局属性等。ServletContext 接口也定义了一些方法,用于获取 Web 应用程序的资源、获取请求调度器、获取 Servlet 的配置等。

在实际开发中,Servlet 接口和 ServletContext 接口是开发者经常用到的接口之一。通过实现 Servlet 接口,开发者可以编写自己的 Servlet 类,处理客户端请求并生成响应。而 ServletContext 接口则提供了一些全局的方法和信息,方便开发者共享和访问应用程序的全局资源和信息。

 Servlet、GenericServlet、HttpServlet三者如何演变的?

在我们最初书写JavaWeb代码是通常是这样的,实现Servlet接口和接口中的五个方法,但是我们慢慢发现,在实现的所有方法中,我们大多数都是在service()f方法中书写我们的代码,而其他的代码基本上是没有用的,但又必须去实现,导致我们的代码很不美观。

        import jakarta.servlet.*;

        import java.io.IOException;

public class demo01 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) 
throws ServletException, IOException {

    }

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

    @Override
    public void destroy() {

    }
}

之后就有人进行代码的改进,于是GenericServlet诞生,将GenericServlet定义为抽象类,其源代码如下:

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {

      public GenericServlet() {
    }

    public void destroy() {
    }


    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }


    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }


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

}

将原来Servlet接口中的一些不经常用的方法封装成普通方法,同时将Service()方法封装成为一个抽象方法,该方法必须在子类中去实现。由此处理了直接实现Service接口时的麻烦与冗杂,我们直接继承GenericServlet类,其代码如下:

class App01 extends GenericServlet{

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) 
throws ServletException, IOException {

    }
}

简洁和优雅许多,无须再实现其他方法,而仅仅需要实现GenericServlet抽象类中的service()方法,大大提高了开发效率;

从GenreicServlet到HttpServlet的转变

由于我们编写的程序是在浏览器和服务器之间运行的,而浏览器和服务器之间的信息传递需要遵循一套规范,而其中最常见的规范是http规范,通过http规范,可以很好地实现同浏览器与服务器之间的解耦性。(即我们不需要为了不同的浏览器和服务器编写不同的代码,一套代码即可走天下)一旦我们的代码是基于http协议的,那么有没有更好的办法,使我们更好地编写代码呢?

public abstract class HttpServlet extends GenericServlet {
 
    public HttpServlet() {
    }
    
    protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
       …………………………………………………………………………………………………//其中代码省略
    }

    public void service(ServletRequest req, ServletResponse res) 
throws ServletException, IOException {
        HttpServletRequest request;
        HttpServletResponse response;
        try {
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)res;
        } catch (ClassCastException var6) {
            throw new ServletException(lStrings.getString("http.non_http"));
        }

        this.service(request, response);
    }


}

在这一个service(ServletRequest req, ServletResponse res)方法中,将req和res强制向下转型,转型成HttpServlet类型的变量,以此传入上方service(HttpServletRequest req, HttpServletResponse resp)的方法中。

当然我们写代码的时候不一定必须继承HttpServlet类,也可以继续继承GenericServlet抽象类,但是我们不能享受到HttpServlet类中所提供的一些特殊的服务了,比如405报错。

以上就是本篇的知识点了,如果这篇文章帮助了你,还请点赞加关注,后续笔者会有更多的优秀文章进行推送。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值