为什么Servlet程序的init(ServletConfig config)中需要调用父类的init方法

本文探讨了Servlet初始化过程中super.init(config)方法的重要性,并通过一个具体的示例分析了未调用此方法导致的问题。揭示了super.init(config)对于正确配置Servlet及避免NullPointerException异常的关键作用。

说明:本文代码测试于:idea2018; tomcat 9.0



当我们通过IDEA自动生成init(ServletConfig config)方法时,默认创建一句调用父类init()方法的语句

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

但是调用父类的构造方法super.init(config);是必须的吗?如果我们将其删掉会怎样呢?

@WebServlet(name = "HelloServlet", urlPatterns = "/hello",
    initParams = {
        @WebInitParam(name = "hello2021", value = "123")
    }
)
public class HelloServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("hahaha");
    }
	// 为简化问题,不考虑 doPost() 方法
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	// 获取当前 Servlet 的 config 对象
        ServletConfig config = getServletConfig();
        // 输出当前 Servlet 程序的别名
        System.out.println(config.getServletName());
    }
}

浏览器访问HelloServlet项目,报错:

HTTP Status 500 – Internal Server Error
Type 异常报告

描述 服务器遇到一个意外的情况,阻止它完成请求。

Exception

java.lang.NullPointerException
	chapter1.HelloServlet.doGet(HelloServlet.java:33)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note 主要问题的全部 stack 信息可以在 server logs 里查看

分析报错信息可知,报错的原因是:java.lang.NullPointerException,报错语句是:System.out.println(config.getServletName());

报错信息中提到HelloServlet.java:33,实际上就是该语句:System.out.println(config.getServletName());

缩小范围,可知是该语句引起的报错:config.getServletName(),结合报错类型是空指针异常,所以可以推断config的值为空。而config是由getServletConfig()方法返回的,查看getServletConfig()源代码

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
	private transient ServletConfig config;
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    public ServletConfig getServletConfig() {
        return this.config;
    }
}

简单说明一下,在自定义的Servlet项目中(本文即是HelloServlet),init(ServletConfig config)的父类方法是GenericServlet类中的构造方法,覆盖的getServletConfig()方法同样也是GenericServlet中的。读者可以直接查看源码验证。

综上可知,super.init(config);的作用是将config传入GenericServlet,初始化超类中的ServletConfig属性,以便能通过getServletConfig()方法在子类中获得config对象
在这里插入图片描述


根据Servlet程序的继承结构可知,自定义的Servlet程序的直接父类是HttpServletHttpServlet的父类是GenericServlet,而自定义的Servlet程序直接可以覆盖GenericServlet中的方法的原因是HttpServlet没对某些方法进行重写。在这里插入图片描述



参考文章:

  1. servlet中的init方法中为什么总要有个super.init
  2. 尚硅谷最新版JavaWeb全套教程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值