サーブレットベースのアプリケーションでどこに配置し、構成リソースファイルを読み取るか?


222

私のWebアプリケーションでは、などの事前定義されたユーザーのセットに電子メールを送信する必要がfinance@xyz.comあるため、それを.propertiesファイルに追加して、必要なときにアクセスしたいと思います。これは正しい手順ですか?正しい場合、どこにこのファイルを配置すればよいですか?ソースとJSPファイル用に2つの別々のフォルダーがあるNetbeans IDEを使用しています。


JNDIはおそらくソリューションかもしれませんか?
バジルブルク

回答:


464

それはあなたの選択です。Java Webアプリケーションアーカイブ(WAR)には基本的に3つの方法があります。


1.クラスパスに配置します

ClassLoader#getResourceAsStream()クラスパス相対パスでロードできるように:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);

ここではfoo.propertiesWebアプリケーション、例えばWebアプリケーションのデフォルトのクラスパスでカバーされている根の一つに置かれることになっている/WEB-INF/lib/WEB-INF/classes、サーバーの/lib、またはJDK / JREの/lib。プロパティファイルがwebapp固有である場合、それをに配置するのが最善です/WEB-INF/classes。IDEで標準のWARプロジェクトを開発している場合は、それをsrcフォルダー(プロジェクトのソースフォルダー)にドロップします。Mavenプロジェクトを使用している場合は、/main/resourcesフォルダーにドロップします。

または、デフォルトのクラスパス以外の場所に配置して、そのパスをアプリサーバーのクラスパスに追加することもできます。たとえばTomcatでは、のshared.loaderプロパティとして構成できますTomcat/conf/catalina.properties

foo.propertiesそれをJavaパッケージ構造に配置した場合は、com.example以下のようにロードする必要があります。

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...

コンテキストクラスローダーのこのパスは、で開始しないでください/。などの「相対」クラスローダーを使用している場合のみ、SomeClass.class.getClassLoader()実際にで開始する必要があります/

ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...

ただし、プロパティファイルの可視性は、問題のクラスローダーによって異なります。クラスをロードしたクラスローダーと同じクラスローダーにのみ表示されます。したがって、クラスがwebappクラスローダーではなくサーバー共通クラスローダーなどによってロードされ、プロパティファイルがwebapp自体の内部にある場合、そのクラスは表示されません。コンテキストクラスローダーが最も安全な方法です。そのため、プロパティファイルをクラスパスの「どこにでも」置くことができ、サーバーから提供されたものをWebアプリケーションからオーバーライドできるようにすることもできます。


2.ウェブコンテンツに入れます

これServletContext#getResourceAsStream()で、webcontent相対パスを使用してロードできます。

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...

私はファイルを/WEB-INFフォルダーに配置することを実証したことに注意してください。またことに注意してServletContextいずれかであるHttpServletクラス継承でわずかアクセス可能GenericServlet#getServletContext()と中FilterによりますFilterConfig#getServletContext()。サーブレットクラスに属していない場合、通常はを介して単に注入でき@Injectます。


3.ローカルディスクファイルシステムに配置する

java.io絶対ローカルディスクファイルシステムパスで通常の方法でロードできるように:

InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...

絶対パスを使用することの重要性に注意してください。相対ローカルディスクファイルシステムのパスは、Java EE Webアプリケーションでは絶対に必要です。以下の最初の「関連項目」リンクも参照してください。


どちらを選ぶ?

保守性については自分の長所と短所を比較検討してください

プロパティファイルが「静的」であり、実行時に変更する必要がない場合は、WARに保持できます。

毎回WARを再ビルドおよび再デプロイする必要なしにWebアプリケーションの外部からプロパティファイルを編集できるようにしたい場合は、プロジェクトの外部のクラスパスに配置します(必要な場合は、クラスパスにディレクトリを追加します)。

Properties#store()メソッドを使用してWebアプリケーションの内部からプログラムでプロパティファイルを編集できるようにする場合は、Webアプリケーションの外部に配置します。にはProperties#store()が必要なWriterので、ディスクファイルシステムのパスを使用して回避することはできません。そのパスは、VM引数またはシステムプロパティとしてWebアプリケーションに渡されます。念のため、は絶対に使用しないでgetRealPath()ください。変更が元のWARファイルに反映されないという単純な理由で、デプロイフォルダ内のすべての変更は再デプロイ時に失われます。

以下も参照してください。


2
「個人的には、プロジェクト外のクラスパスに配置することを好む(クラスパスに新しいパスを追加する)」と混乱していますが、例を挙げていただけますか?
ブランクマン、2011

4
@Blankman彼はおそらく、新しいフォルダーを作成し、そこにすべてのカスタム構成ファイルを配置し、そのフォルダーをクラスパスに追加することを意味します。したがって:1)どこかに「appconfs」というフォルダーを作成します(偶数である可能性があり/etc/appconfsます)2)そのフォルダーをアプリサーバー/ドメインのクラスパスに追加します。2番目のステップはアプリサーバー固有です。その一般的な例はないと思います。
Tuukka Mustonen、2012年

Re:2:なぜ"WEB-INF/filename.properties""/WEB-INF/filename.properties"/冒頭に注意)の両方が機能するのですか?どちらか一方を優先する理由はありますか?
Mr_and_Mrs_D 2013

この問題は過去1日間解決されました。プロパティファイルを読み込めません。2箇所からロードできます。1つはシステムディレクトリで、もう1つはローカルドライブです。それはlocalhostで動作します。しかし、私はそれをアマゾンに展開したいと思います。
Arun Raja

私はnetbeans IDEを使用しており、プロパティファイルをWebページ/リソースに保持しています。「./Web Pages / resources / config.properties」としてアクセスしようとします。アクセスできません。私を助けてください。
Arun Raja

9

警告の言葉:設定ファイルをWEB-INF/classesフォルダーに入れ、IDE(たとえばEclipse)がクリーン/再構築を行うと、Javaソースディレクトリにない限り、confファイルが破壊されます。BalusCの素晴らしい答えは、オプション1のそれを暗示していますが、私は強調を加えたかったのです。

私は、EclipseでWebプロジェクトを「コピー」すると、ソースフォルダーからクリーンアップ/再構築を行うという難しい方法を学びました。私の場合、POJO Javaライブラリから「リンクされたソースディレクトリ」を追加した場合、それはWEB-INF/classesフォルダーにコンパイルされます。そのプロジェクト(Webアプリプロジェクトではない)でクリーンアップ/再構築を行うと、同じ問題が発生しました。

confをPOJO srcフォルダーに入れることを考えましたが、これらのconfはすべて、フォルダー内にあるサードパーティライブラリ(QuartzやURLRewriteなど)のWEB-INF/libためのものであり、意味がありませんでした。私はそれに移動したときに、Webプロジェクトの "src"フォルダーに配置することをテストする予定ですが、そのフォルダーは現在空であり、confファイルが含まれているように見えません。

中のconfファイルを置くためのI投票のでWEB-INF/commonConfFolder/filename.properties次の Balusオプション2であるclassesフォルダに。


1
設定ファイルをWEB_INFのサブフォルダーに配置した場合、どのようにしてそれに到達しますか?「configFiles / prop.properties」と言っても運が悪かった
JesseBoyd

これは、プロパティファイルを 'Java Resources / src /'に置いても機能します。私のパッケージの1つからは機能せず、srcのルートにある必要があります。クラスフォルダーが削除されるという警告は有効な懸念事項です。
JesseBoyd 2017

6

例:web.xmlファイルでタグ

<context-param>
        <param-name>chatpropertyfile</param-name>
        <!--  Name of the chat properties file. It contains the name and description                   of rooms.-->     
        <param-value>chat.properties</param-value>
    </context-param>

そして、あなたはこのようにあなたのプロパティを宣言することができるchat.properties

例:

Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.

5

クラスパスにある必要があります(ビルドの一部として、.warの/ WEB-INF / classesの下にあることを確認してください)。


こんにちはアイデアをありがとう、しかしそれは指定されたファイルを見つけることができないことを私に告げます、はいそれはパスを与える方法のパスの問題
sansknwoledge

3

ソースフォルダーを使用すると、ビルドするたびにこれらのファイルが自動的にクラスディレクトリにコピーされます。

プロパティファイルを使用する代わりに、XMLファイルを使用します。

データが小さすぎる場合は、web.xmlを使用してプロパティにアクセスすることもできます。

これらの方法では、変更を反映するためにアプリサーバーを再起動する必要があることに注意してください。



1
ファイルがWEB-INF / classesフォルダーにある場合、自動的にクラスパスに設定されます
Kalpak

2

コードがapp.propertiesなどのファイルを探しているとします。tomcatのbinディレクトリにsetenv.shを作成して、このファイルを任意のディレクトリにコピーし、このディレクトリをクラスパスに追加します。

tomcatのsetenv.shで(このファイルが存在しない場合は作成してください。tomcatはこのsetenv.shファイルをロードします。 #!/bin/sh CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"

./webapps//WEB-INF/classes/app.propertiesにプロパティファイルを含めないでください。

TomcatクラスローダーはWEB-INF / classes /からのものをオーバーライドします

良い読み物:https : //tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.