在项目的开发中遇到了在servlet中使用getServletContext空指针的错误,觉得挺有意思的,下面解释一下。
网上查了许多都说是重写了init方法造成的,但我并不是,所以稍微研究了一下。
首先是为什么servlet里头会有servletContext对象,这是web服务器在实例化你的对象之前调用了init(ServletConfig)方法,所以才会有,如果你重写了init方法并且没有调用super.init(),你自然无法令web服务器给你servletContext对象了。但是还有一种情况,那就是你自己实现了实例化,比如用反射写工具的时候就会出现,因为这是你自己实例化的,web服务器就不会调用init方法,因此是访问不到servletContext对象的。
总的来说目前两种情况会造成getServletContext出现空指针异常。
1.重写init方法时没有调用super.init(servletContext);
2.对象是你自己实现实例化的,没有通过web服务器替你创建,因此出现空指针异常;
错误证明如下:
public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// localhost:8080/store/productServlet?method=addProduct 这是访问时的url ognl加上method的键值对告知调用哪个方法
String method = req.getParameter("method");
//如果这个method有问题,就调用execute方法
if (null == method || "".equals(method) || method.trim().equals("")) {
method = "execute";
}
//获取当前的类对象类型
Class<? extends BaseServlet> clazz = this.getClass();
try {
Object object = clazz.newInstance();
//根据method找方法,因为子类拥有父类的空间我们这个url是访问到子类去了,然后容器调用service方法,
//就来这里了,这个method就是在找子类的方法,没有就reutn null,不影响
Method md = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
if(null!=md){
String jspPath = (String) md.invoke(object, req, resp);
if (null != jspPath) {
//转发,因为servlet一般最后一部都是转发到另一个地方去,所以干脆放这个工具里头,不想转发return null就好了
req.getRequestDispatcher(jspPath).forward(req, resp);
}
}
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
}
这是一个工具类,用于调用其子类的某个方法来减少servlet的数量,注意这里的子类是通过反射机制得到的,也就是非tomcat创建,没有调用init方法的。
http://localhost:8080/servletContext/AdminProductServlet?method=addProduct
浏览器上输入URL来进行访问。
16行也就是我们的getServletContext出错了,空指针异常。