以下代码是我们用于项目的“基础”servlet:
public class MyServlet extends Servlet {
private static final long serialVersionUID = 1L;
protected Connection conn;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
}
protected void connectDB() throws NamingException, SQLException {
// get database settings
InitialContext cxt = new InitialContext();
DataSource ds =(DataSource)cxt.lookup( "java:/comp/env/jdbc/MyDB" );
conn = ds.getConnection();
}
protected void closeDB() throws SQLException {
try {
if (conn!=null) conn.close();
}
finally {
conn = null;
}
}
protected void addCacheControl(HttpServletResponse response) {
response.setHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, pre-check=0, post-check=0");
response.setHeader("Pragma", "no-cache");
}
}
例如SomeServlet extends MyServlet
...
现在SomeServlet
在浏览器中访问它对JSP页面执行forward()
然后刷新一段时间(比如10秒)。
在页面打开一段时间后,此代码抛出NullPointerException:
stmt = conn.prepareCall("{call sp_someSP(?, ?, ?)}");
答案 0 :(得分:1)
您不能像这样使用Servlet的实例字段,因为它将由多个线程共享。
您需要通过程序显式传递连接作为参数和局部变量(以便它们存在于堆栈中,并且每个线程都有自己的版本),或者如果您想要更“全局”,可以使用ThreadLocal做法。当您的请求完成时,ServletFilter也可以可靠地关闭ThreadLocal连接。