我正在尝试使用Servlet 3.0为Tomcat webapp创建一个访问计数器。我想在Tomcat启动时将InitServlet加载到内存中。以下是我的java代码:
package com.yehang;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name="InitServlet",urlPatterns={"/InitServlet"},loadOnStartup=1)
public class InitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public InitServlet() {
super();
}
public void init(ServletConfig config) throws ServletException {
// read the nums from the recoder.txt
// 1. get the file path
String filePath = this.getServletContext().getRealPath("recorder.txt");
//System.out.println(filePath);
try {
// 2. open a filereader
FileReader fileReader = new FileReader(filePath);
// 3. put the fileReader into a bufferedreader
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 4 read the nums from the bufferedreader
String nums = bufferedReader.readLine();
bufferedReader.close();
System.out.println(nums);
// put nums into context
this.getServletContext().setAttribute("nums", nums);
// cloese the stream(important)
fileReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
// write the nums to the recoder.txt
// 1. get the file path
String filePath = this.getServletContext().getRealPath("recorder.txt");
try {
// 2. open a fileWriter
FileWriter fileWriter = new FileWriter(filePath);
// 3. put the fileWriter into a bufferedWriter
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 4. get the nums from the context
String nums = (String) this.getServletContext()
.getAttribute("nums");
// write into the file
bufferedWriter.write(nums);
// close the stream(important)
bufferedWriter.close();
fileWriter.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset = utf-8");
PrintWriter out = response.getWriter();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
我的设计是将此类加载到内存中,并在Tomcat启动时调用init()方法。 init()方法将从WebContent下的recorder.txt中读取一个数字,并将该数字放入上下文中。当Tomcat停止时,它将调用destroy()方法从上下文中获取新数字并写回recorder.txt文件。 .txt文件中的数字将会更新。
然而,当我启动Tomcat时,我收到了以下错误:
java.lang.NullPointerException
at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
at com.yehang.InitServlet.init(InitServlet.java:30)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5229)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5516)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
Dec 28, 2014 1:36:48 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /Counter threw load() exception
java.lang.NullPointerException
at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
at com.yehang.InitServlet.init(InitServlet.java:30)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5229)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5516)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
当我尝试打印输出文件路径时,它为空。
甚至在对文件路径进行硬编码之后:
String filePath = "/Users/yehang/Documents/workspace/Counter/WebContent/recorder.txt";
此代码仍然无效。它无法从文件中读取数字。
null
java.lang.NullPointerException
at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123)
at com.yehang.InitServlet.init(InitServlet.java:42)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5229)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5516)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:744)
我打印出的nums为null。我不知道为什么。我在另一个servlet的doGet()方法下尝试了几乎相同的代码,它运行良好。原因必须是init()和doGet()方法之间的区别。但我不知道。我是servlet的新手。
答案 0 :(得分:1)
看起来你的servlet没有正确初始化。您在被覆盖的init(ServletConfig)
中的第一个电话应该是
super.init(config);
或者您应该覆盖init()