0

サーブレットに関するこの本を読んでいるときに、FileWriterクラスを使用して、サーブレットが破棄される前に永続的な状態を保存する例に出くわしました。例をテストし、正常に動作します。これはコードです。

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ファイルをコピーして貼り付け、jarファイルを開いて「InitDestroyCounter.initial」ファイルを探しますが、そこに見つからないため、glassfishがこの作成されたファイルをどこに保存するのか疑問に思いました。

4

5 に答える 5

2

(答えではありませんが、読みやすいコメントには長すぎます。)

  1. ファイルを戦争に保存することはできません。1

  2. 絶対パスに書き込むことにより、既知のファイルの場所に書き込む必要があります。これは、JNDI、initコンテキストパラメータ、起動パラメータ、環境変数などを介して定義できます。

  3. IMOは、戦争でなくてもWebアプリに書き込むべきではありません。ファイルはデプロイメントメカニズムに翻弄され、消去される可能性があるためです。

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アクセスを回避する必要があることに注意してください。JavaEEプログラマーはファイルに書き込みません。

于 2013-01-27T20:14:10.177 に答える
1

どのJavaWeb/ 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

保証は、GlassFishがasadminを使用して開始された場合にのみ適用されます。

注:私はコードを書いたので、確かに知っています!

于 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 に答える