无法使用.getServletContext()。getRealPath()获取Tomcat 7下的真实文件路径

时间:2014-12-28 18:51:07

标签: servlets

我正在尝试使用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的新手。

1 个答案:

答案 0 :(得分:1)

看起来你的servlet没有正确初始化。您在被覆盖的init(ServletConfig)中的第一个电话应该是

super.init(config);

或者您应该覆盖init()