一、我们编译Servlet类直接实现Servlet接口有什么缺点?
在接口中的 5 个方法中,只有service 方法使我们常用的,但是要实现其余 5 个方法,这其实是很蠢的。
二、那么我们应该怎么办呢?
我们可以编写一个通用的GenericServlet类,用这个类实现 Servlet 接口。这个类是抽象的,将 service 方法设置成抽象方法 。每个Servlet类不在实现 Servlet接口了,而是继承这个通用的GenericServlet 类【这个通用的类就是 适配器,这也是Servlet规范中的一员】
//通用的Servlet类
public abstract class GenericServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
抽象方法:没有方法体。
*/
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
以下为俩个 Servlet 类:
编辑配置文件:
当我们访问 BServlet时:
当我们访问 CServlet 时:
三、能不能改造GenericServlet适配器?更利于子类的编写
- 当我们提供一个GenericServlet之后,里面 init 方法还会执行吗?
- 会的,子类继承 GenericServlet,会执行 init 方法。
- init 方法中的 ServletConfig 对象 是谁创建的?谁传过来的呢?
- Tomcat 服务器。Tomcat 先创建 Servlet 对象。通过对象调用 init 方法。
- 那么我们如何在子类中获取到 ServletConfig 呢?
- ServletConfig 在init方法中是一个 局部变量,可以将这个局部变量赋给成员变量。通过 getServletConfig 这个方法获取到 。
- 有没有可能在子类中需要重写 init 方法?
- 是有可能的,但是重写 init 方法 会破坏 config 的值。
- 所以我们一般不会允许 GenericServlet 中 init 方法进行重写。会在init方法上加一个 final 修饰。
- 但是我们可以再 GenericServlet 中重载一个 init 方法。让子类对重载的 init 方法进行操作
- 其实适配器不用我们自己写,只是了解以下源码。在 javax.servlet 包下已经写好了。只需继承即可【有的在 jakarta.servlet包下。我这个版本较低】
- 这个是写好的 GenericServlet ,几乎和我们自己写一样。