0

在阅读有关 servlet 的这本书时,我遇到了一个示例,它使用 FileWriter 类在 servlet 被销毁之前保存它的持久状态。测试了示例并且工作正常,这是代码:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class InitDestroyCounter extends HttpServlet {

  int count;

  public void init(ServletConfig config) throws ServletException {
    // Always call super.init(config) first  (servlet mantra #1)
    super.init(config);

    // Try to load the initial count from our saved persistent state
    try {
      FileReader fileReader = new FileReader("InitDestroyCounter.initial");
      BufferedReader bufferedReader = new BufferedReader(fileReader);
      String initial = bufferedReader.readLine();
      count = Integer.parseInt(initial);
      return;
    }
    catch (FileNotFoundException ignored) { }  // no saved state
    catch (IOException ignored) { }            // problem during read
    catch (NumberFormatException ignored) { }  // corrupt saved state

    // No luck with the saved state, check for an init parameter
    String initial = getInitParameter("initial");
    try {
      count = Integer.parseInt(initial);
      return;
    }
    catch (NumberFormatException ignored) { }  // null or non-integer value

    // Default to an initial count of "0"
    count = 0;
  }

  public void doGet(HttpServletRequest req, HttpServletResponse res) 
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    count++;
    out.println("Since the beginning, this servlet has been accessed " +
                count + " times.");
  }

  public void destroy() {
    saveState();
  }

  public void saveState() {
    // Try to save the accumulated count
    try {
      FileWriter fileWriter = new FileWriter("InitDestroyCounter.initial");
      String initial = Integer.toString(count);
      fileWriter.write(initial, 0, initial.length());
      fileWriter.close();
      return;
    }
    catch (IOException e) {  // problem during write
      // Log the exception.
    }
  }
}

停止 glassfish 服务器后,我从部署文件夹复制/粘贴 war 文件,解压缩并查找“InitDestroyCounter.initial”文件,但在其中找不到,所以我想知道 glassfish 将这个创建的文件保存在哪里?

4

5 回答 5

2

(不是答案,但对于清晰的评论来说太长了。)

  1. 您不能将文件保存到战争中。1

  2. 您应该通过写入绝对路径来写入已知文件位置。这可以通过 JNDI、初始化上下文参数、启动参数、环境变量等来定义。

  3. IMO 即使不是战争,您也不应该将其写入网络应用程序,因为您的文件将受制于您的部署机制,并且可能会被清除。

1 是的,你可以。不。

于 2013-01-27T19:08:46.887 回答
2

所有其他关于 WAR 修改都是正确的,但对于上面的代码:

这个

FileWriter fileWriter = new FileWriter("InitDestroyCounter.initial");

是一个捷径

File f = new File("InitDestroyCounter.initial");
FileWriter fileWriter = new FileWriter(f);

所以请随意询问 File 对象的绝对位置:

System.out.println(f.getAbsolutePath());

总而言之,您上面的所有代码都将使用 JVM 的当前/工作目录来存储和读取文件。请记住,应根据 Java EE 规范避免 I/O 访问:Java EE 程序员不写入文件

于 2013-01-27T20:14:10.177 回答
1

在任何 java web/app 服务器中,您不应该期望直接在部署的存档中进行修改。相反,它会在当前工作目录中写入文件。

如果您在 linux 中,我找到了一个地方(http://www.java.net/forum/topic/glassfish/glassfish/paths-glassfish),他们声称您可以使用以下命令检索当前的工作目录:

asadmin generate-jvm-report | grep "user.dir" 

所以你可以看到它说什么。

但是据我所知,它应该是config服务器的目录。所以也许看看那里的文件。

于 2013-01-27T19:08:25.990 回答
1

GlassFish 绝对保证当前工作目录将始终是域的“config”目录。例如在默认情况下:

/domains/domain1/config

该保证仅适用于使用 asadmin 启动 GlassFish 的情况。

注意:我写了代码,所以我确定!

于 2013-01-28T18:10:09.563 回答
0

从我所做的答案和测试中,所有这些都可以指向路径:

System.getProperty("user.dir")

new File(".").getAbsolutePath()

getAbsolutePath();

正如你在这里看到的:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class InitDestroyCounter extends HttpServlet
{
    int Cnt;

    String FR_File_Str;

    @Override
    public void init(ServletConfig ServlConf) throws ServletException
    {
        // Always call super.init(ServletConfig) first;
        super.init(ServlConf);

        // Try to load the initial Cnt from our saved persistent state;
        try
        {
            File FR_File = new File("InitDestCounter.init");
            FileReader FR = new FileReader(FR_File);

            BufferedReader BR = new BufferedReader(FR);

            String Initial_str = BR.readLine();

            Cnt = Integer.parseInt(Initial_str);

            FR_File_Str = FR_File.getAbsolutePath();

            return;
        }
        catch(FileNotFoundException Ignored){} // No saved state;
        catch(IOException Ignored){} // Problem during read;
        catch(NumberFormatException Ignored){} // Corrupted saved state;

        // No luck with the saved state, check for and init parameter;
        String Initial_str = getInitParameter("initial_cnt");

        try
        {
            Cnt = Integer.parseInt(Initial_str);
            return;
        }
        // Null or non-integer value;
        catch(NumberFormatException NFE){}

        // Default, if non of the above worked;
        Cnt = 0;
    }

    @Override
    public void doGet(HttpServletRequest  Request,
                      HttpServletResponse Response)
                      throws ServletException, IOException
    {
        Response.setContentType("text/html");

        PrintWriter PW = Response.getWriter();

        Cnt++;

        PW.println("<H4>Since the beginning this servlet had been "+
                   "accessed "+Cnt+" times.</H4>");
        PW.println("<H4>"+System.getProperty("user.dir")+"</H4>");
        PW.println("<H4>"+new File(".").getAbsolutePath()+"</H4>");
        PW.println("<H4>FR_File_Str = "+FR_File_Str+"</H4>");
    }

    public void SaveState()
    {
        // Try to save the accumulated count;
        try
        {
            FileWriter FW = new FileWriter("InitDestCounter.init");

            String Initial_str = Integer.toString(Cnt);

            FW.write(Initial_str, 0, Initial_str.length());

            FW.close();

            return;
        }
        catch(IOException IOE){} // Problem during write;
    }

    @Override
    public void destroy()
    {
        SaveState();
    }
}

出于礼貌,我不会接受我自己的回答。感谢大家的回答和评论。

于 2013-01-30T22:58:16.687 回答