说明:本文代码测试于: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程序的直接父类是HttpServlet,HttpServlet的父类是GenericServlet,而自定义的Servlet程序直接可以覆盖GenericServlet中的方法的原因是HttpServlet没对某些方法进行重写。
参考文章:
本文探讨了Servlet初始化过程中super.init(config)方法的重要性,并通过一个具体的示例分析了未调用此方法导致的问题。揭示了super.init(config)对于正确配置Servlet及避免NullPointerException异常的关键作用。

3817

被折叠的 条评论
为什么被折叠?



