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 规范包括以下几个方面的内容:
-
Servlet 接口:定义了 Servlet 的核心接口,以及 Servlet 生命周期方法。
-
Servlet 容器:定义了 Servlet 容器的规范,包括 Servlet 容器的生命周期、管理 Servlet 的方式、加载 Servlet 类、处理请求和响应等方面。
-
Servlet API:定义了 Servlet API,包括 ServletRequest、ServletResponse、HttpServletRequest、HttpServletResponse 等一系列类和接口。
-
部署描述符:定义了 web.xml 部署描述符的规范,这个描述符用于描述 Web 应用程序的部署信息,比如 Servlet 的映射、过滤器、监听器等。
Servlet 规范为 Java Web 应用程序开发提供了一套标准的开发规范和接口,使得不同厂商的 Servlet 容器和开发工具能够实现互操作性,同时也方便了开发者进行跨平台的 Web 应用程序开发。常见的 Servlet 容器包括 Tomcat、Jetty、WebLogic 等。
2.Servlet中的核心接口有什么?
Servlet 规范中定义了两个核心接口:Servlet 和 ServletContext。
-
Servlet 接口是 Servlet API 的核心接口,所有 Servlet 类都必须实现该接口。Servlet 接口定义了一些方法,用于处理来自客户端的请求和生成响应。常用的方法包括:init()、service()、destroy() 等。
-
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报错。
以上就是本篇的知识点了,如果这篇文章帮助了你,还请点赞加关注,后续笔者会有更多的优秀文章进行推送。