web-dev-qa-db-ja.com

サービスベースのアプリケーションで、配置場所と配置リソースファイルの読み方

私のWebアプリケーションでは、[email protected]のような一連の定義済みユーザーにEメールを送信する必要があるので、それを.propertiesファイルに追加して、必要に応じてアクセスします。これは正しい手順ですか?正しい場合は、このファイルをどこに配置すればよいですか? Netbeans IDEを使用しています。これには、ソースファイルとJSPファイル用に2つの別々のフォルダーがあります。

207
sansknwoledge

それはあなたの選択です。 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.propertiesはWebアプリケーションのデフォルトクラスパスでカバーされているルートの1つに配置されることになっています。 Webアプリケーションの/WEB-INF/lib/WEB-INF/classes、サーバーの/lib、またはJDK/JREの/lib。 propertiesファイルがWebアプリケーション固有のものである場合は、それを/WEB-INF/classesに配置することをお勧めします。 IDEで標準のWARプロジェクトを開発している場合は、それをsrcフォルダー(プロジェクトのソースフォルダー)にドロップします。 Mavenプロジェクトを使用している場合は、それを/main/resourcesフォルダーにドロップします。

あるいは、デフォルトのクラスパスの外側に配置して、そのパスをアプリケーションサーバーのクラスパスに追加することもできます。たとえばTomcatでは、shared.loaderTomcat/conf/catalina.propertiesプロパティとして設定できます。

foo.propertiescom.exampleのようなJavaパッケージ構造に配置した場合は、次のようにロードする必要があります。

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");
// ...

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


2. webcontentに入れます

Webcontentからの相対パスを指定して ServletContext#getResourceAsStream() で読み込むことができます。

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

私は/WEB-INFフォルダにファイルを置くことを実証したことに注意してください、そうでなければそれはどのウェブブラウザからでも一般にアクセス可能であったでしょう。また、ServletContextは継承された GenericServlet#getServletContext() によってアクセス可能なHttpServletクラスにあり、Filterには FilterConfig#getServletContext() によってアクセス可能です。サーブレットクラスに入っていない場合は、通常@Injectを介して注入するだけです。


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

絶対ローカルディスクファイルシステムのパスを使って通常のJava.ioの方法で読み込むことができます。

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

絶対パスを使用することの重要性に注意してください。相対ローカルディスクファイルシステムパスは、Java EE Webアプリケーションでは絶対に使用できません。下記の最初の "See also"リンクも参照してください。


どちらを選ぶ?

your独自の保守容易性についての長所と短所を比較してください。

プロパティファイルが「静的」で実行時に変更する必要がない場合は、それらをWARに保存することができます。

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

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

また見なさい:

445
BalusC

警告の言葉:あなたがWEB-INF/classesフォルダーにconfigファイルを置き、そしてあなたのIDE(例えば、Eclipse)がクリーン/再構築をするならば、それらがJavaソースディレクトリになければあなたのconfファイルを無効にするでしょう。 BalusCのすばらしい答えは選択肢1のそれをほのめかしていますが、私は強調したいと思いました。

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

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

それで私はconfファイルをWEB-INF/commonConfFolder/filename.propertiesnextにclassesフォルダに入れることに賛成します。これはBalusのオプション2です。

8
Ed Pike

例: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.
6

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

5
Taylor Leese

ソースフォルダを使用して作成することができるので、これらのファイルは自動的にclassesディレクトリにコピーされます。

プロパティファイルを使用する代わりに、XMLファイルを使用してください。

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

変更を反映させるには、これらのいずれの方法でもアプリサーバーの再起動が必要になります。

3
Kalpak

コードが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

1
Thar