Webプロジェクトの構成をWebプロジェクトの外部(ear/warファイル)に保存したい。アプリケーションは、実行中のコンテナー(WebSphere/JBossなど)を認識してはなりません。
これを処理するための最良の方法は何ですか?
JNDIはクリーンな方法ですか? JNDIで問題を解決できる場合、どのように構成すればよいですか? (カスタムオブジェクト?)
私の場合、SOAP/WSエンドポイントには単純なKey =>値のペア(String、String)しかありません。
WARファイルの外部のプロパティファイルを読み取るには、これを参照してください 質問 。
JNDIから変数値を読み取るには、これを参照してください 質問 。これが最善の解決策だと思います。次のコードで文字列変数を読み取ることができます。
Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("Java:comp/env/myvar");
上記のコードはすべてのコンテナで機能します。 Tomcatでは、conf /server.xmlで次のように宣言します。
<GlobalNamingResources ...>
<Environment name="myvar" value="..."
type="Java.lang.String" override="false"/>
</GlobalNamingResources>
上記はグローバルリソースを作成します。アプリケーションのコンテキストでリソースを定義することもできます。ほとんどのコンテナでは、JNDIリソースはMBeans管理コンソールから利用できます。それらのいくつかは、それらを編集するためのグラフィカルインターフェイスを提供します。変更が加えられた場合、せいぜいアプリケーションの再起動が必要です。
JNDIリソースの定義および編集方法は、コンテナー固有です。適切な設定を適用するのは、コンフィギュレーター/管理者の仕事です。
JNDIが提供する利点は次のとおりです。
さまざまな開発者向けにWebアプリをデプロイする場合、およびAmazonのEC2で同様の構成要件がありました。構成をバイナリコードから分離するにはどうすればよいですか?私の経験では、JNDIは複雑すぎて、使用するにはコンテナー間で大きく異なります。また、XMLを手動で編集すると、構文エラーの影響を非常に受けやすいため、アイデアは破棄されました。いくつかのルールに基づいた設計でこれを解決しました。
1)単純なname = valueエントリのみを使用する必要があります
2)新しい構成は、1つのパラメーターのみを変更することでロード可能である必要があります
3)WARバイナリは、再パッケージせずに再構成可能である必要があります
4)機密パラメータ(パスワード)がバイナリにパッケージ化されることはありません
すべての構成に.propertiesファイルを使用し、System.getProperty("domain");
を使用して適切なプロパティファイルをロードすることで、要件を満たすことができました。ただし、システムプロパティはファイルのURLを指していません。代わりに、使用する構成を指定するために「ドメイン」と呼ばれる概念を作成しました。構成の場所は常に次のとおりです。$HOME/appName/config/$DOMAIN.properties
。
したがって、独自の構成を使用してアプリを実行する場合は、ドメインを自分の名前に設定してアプリを起動します。-Ddomain=jason
起動時に、アプリはファイルをロードします:/home/jason/appName/config/jason.properties
これにより、開発者は構成を共有できるため、再コンパイルや再パッケージ化を行わなくても、テストとデプロイのためにアプリの同じ状態を再作成できます。次に、ドメイン値を使用して、バンドルされたWARの外部の標準の場所から.propertiesをロードします。
次のような本番構成を使用して、ワークステーションで本番環境を完全に再作成できます。-Ddomain=ec2
ロードします:/home/jason/appName/config/ec2.properties
この設定により、環境ごとに異なる構成を使用して、コンパイルされたバイナリの正確に1セットで開発/ QA /リリースサイクルを実行できます。パスワードなどがバイナリにバンドルされるリスクはなく、ユーザーは構成を共有して、発生している問題を再現できます。
環境変数を使用して、構成が含まれているURL(おそらくfile:// URL)をポイントします。これはセットアップが非常に簡単で、JNDIインフラストラクチャを必要としません。
ここにいくつかのサンプルコードがあります(メモリから入力されました-私はこれをコンパイル/テストしていません):
public void loadConfiguration() {
String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more
// Specific variable name.
if(configUrlStr == null || configUrlStr.equals("") {
// You would probably want better exception handling, too.
throw new RuntimeException("CONFIG_URL is not set in the environment.");
}
try {
URI uri = new URI(configUrlStr);
File configFile = new File(uri);
if(!configFile.exists()) {
throw new RuntimeException("CONFIG_URL points to non-existant file");
}
if(!configFile.canRead()) {
throw new RuntimeException("CONFIG_URL points to a file that cannot be read.");
}
this.readConfiguration(configFile);
} catch (URISyntaxException e) {
throw new RuntimeException("Malformed URL/URI in CONFIG_URL");
}
}
クラスパス上にある通常のJavaプロパティファイルで、プロパティをロードするだけですか?
それは簡単でとてもシンプルです..何かが足りない場合を除いて
私のお気に入りの場所は次のとおりです。環境変数とプロパティファイル(上記のJaredとkgiannakakisによって提案されたように)。
環境プロパティを格納するデータベーステーブル
ただし、もう1つの簡単な解決策は、データベーステーブルに環境プロパティを格納することです。
アプリケーションがデータベースを使用する場合