Java Webアプリケーションからファイルを読み取りたい。ファイルの絶対パスを指定したくない。Webアプリケーションのディレクトリにファイルを置きたいだけだ。
または
.warファイル(パッケージ化されたWebアプリケーション)と共に配置できます。
ファイルに与える相対パス。 ./filename.csv
を試しましたが、うまくいきませんでした。
=========
WAR
ファイル(パッケージ化されたWebアプリケーション)をクライアントに配信します。このWebアプリケーションは、クライアントによってサーバーにコピーされるファイル(たとえば、SuppliedFile.csv
)を読み取ります。そのため、Webアプリケーションがそのファイルを読み取れるようにするためのメカニズム(アプリケーションサーバーがWAR
をunpakするかどうかに関係なく機能する)が必要です。
注意: サーブレットでSuppliedFile.csv
を使用していません...普通のJavaクラスで使用しています...
本当にファイルからロードする必要がありますか?クラスに沿って(WEB-INF/classesに)配置すると、クラスローダーを使用してInputStreamを取得できます。
InputStream csv =
SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");
システム上の事前に設定されたファイルパスに簡単にアクセスできる場合があります。これは、webappディレクトリに追加されたファイルが失われたり、システム構成によってはwebappが解凍されない場合があるため、望ましい方法です。
サーバーでは、アプリの外部データの「ホームディレクトリ」を指すApp ServerのJVMで設定されたシステムプロパティを定義します。もちろん、これにはApp Serverの構成を変更する必要があり(起動時にJVM_OPTSに-DAPP_HOME = ...が追加されます)、主にApp Serverのコンテキスト外で実行されるコードのテストを容易にします。
サーブレット構成からパスを簡単に取得できます。
<web-app>
<context-param>
<param-name>MyAppHome</param-name>
<param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>
次に、このパスを取得し、ベースパスとして使用して、クライアントから提供されたファイルを読み取ります。
public class MyAppConfig implements ServletContextListener {
// NOTE: static references are not a great idea, shown here for simplicity
static File appHome;
static File customerDataFile;
public void contextInitialized(ServletContextEvent e) {
appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
File customerDataFile = new File(appHome, "SuppliedFile.csv");
}
}
class DataProcessor {
public void processData() {
File dataFile = MyAppConfig.customerDataFile;
// ...
}
}
前述したように、発生する可能性が最も高い問題はセキュリティ制限です。 webappがwebappルートより上のファイルを準備できることを保証するものではありません。ただし、特定のWebアプリケーションへの特定のパスに例外を付与する一般的な簡単な方法があります。
このファイルにアクセスする必要があるコードに関係なく、Webアプリケーション内で実行しているため、これは最初に初期化され、残りのコードが参照するのに便利な値を格納できます例またはそれ以上ですが、単にそれを必要とするコードにパラメーターとしてパスを渡すだけです。
Webサーバーにそのファイルのパスがある場合、 ServletContext.getRealPath() を使用してサーバーのファイルシステムの実際のパスを取得できます。すべてのコンテナでの動作が保証されているわけではないことに注意してください(コンテナはWARファイルを解凍してファイルシステムにコンテンツを保存する必要はありません-ほとんどの場合はそうです)。また、仮想パスがないため、/ WEB-INF内のファイルでは機能しません。
代替方法は、URIを返す ServletContext.getResource() を使用することです。このURIは「file:」URLの場合がありますが、それを保証するものではありません。
多くの一般的なJava Jenkins および Nexus を含むwebapps、このメカニズムを使用します:
オプションで、サーブレットのcontext-param/init-paramを確認。これにより、context.xml
を使用して、サーブレットコンテナごとに複数のwebappインスタンスを構成できます。これは、WARの変更またはサーバー設定の変更(Tomcatの場合)によって実行できます。
環境変数を確認( System.getenv を使用)、設定されている場合は、そのフォルダーをアプリケーションデータフォルダーとして使用します。例えばJenkinsはJENKINS_HOME
を使用し、NexusはPLEXUS_NEXUS_WORK
を使用します。これにより、WARを変更せずに柔軟に構成できます。
それ以外の場合、ユーザーのホームフォルダー内のサブフォルダーを使用、例: $HOME/.yourapp
。 Javaコードでは、これは次のようになります。
final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
別の方法は、URIを返すServletContext.getResource()を使用することです。このURIは「file:」URLの場合がありますが、それを保証するものではありません。
File:... URLである必要はありません。 JVMが読み取れるURLであることが必要なだけです。