2009-11-13 17 views
10

Tomcatは「バーチャルホスティング」サポートのビルドを提供しています。エンジン/ Webアプリケーションは、ドメインのリストを担当するように設定できます。これらのドメインは、特別なxmlディレクティブを使用してserver.xml/context.xmlファイルに配置する必要があります。Tomcat:仮想ホストをプログラムで変更しますか?

=> Tomcatの設定(一般的に)、特にWebアプリケーション/エンジンの「仮想ホスト」をプログラムによって変更する可能性はありますか?

たとえば、新しいユーザーがサインアップする場合、自分のドメインを「受け入れられた仮想ホスト/ドメイン」のリストに追加する必要があります。私が現在考えている唯一の方法は、XMLファイルをスクリプトで変更し、Tomcatを再起動することです。

プログラムを追加する方法はありますか?

ありがとうございました! Jan

答えて

6

Tomcatには、新しい仮想ホストを作成するためのAPIが用意されています。これに必要なラッパーオブジェクトにアクセスするには、ContainerServletを実装する必要があります。あなたは確かのappBaseディレクトリが存在するようにする必要があり、あなたがserver.xmlファイルに新しいホストを永続化する方法を見つけるために持っているか、あなたは再起動時にホストを失う

Context context = (Context) wrapper.getParent(); 
    Host currentHost = (Host) context.getParent(); 
    Engine engine = (Engine) currentHost.getParent(); 

    StandardHost host = new StandardHost(); 
    host.setAppBase(appBase); 
    host.setName(domainName); 

    engine.addChild(host); 

、このような仮想ホストを作成することができます。

しかし、このアプローチはめったに動作しません。ユーザーが独自のアプリケーションを実行している場合、Tomcatの別々のインスタンスを実際に実行して、アプリケーションをより良くサンドボックス化することができます。例えば1つのアプリがメモリ不足になっても、他のアプリはすべて終了しません。

アプリを提供する場合は、1つのホスト(defaultHost)を使用できます。 Hostヘッダーからドメイン名を取得し、コード内のドメイン固有のものを実行できます。

+1

こんにちはZZコーダー、あなたの答えに感謝します。面白いことに、これについて聞いたことがない、Tomcatのホストとエンジンにアクセスする方法があることを知っていることは素晴らしいことです。 – jan

+0

@Coder、 'wrapper'オブジェクトを取得する方法 – Kainix

+0

@Kainix setter setWrapper()を持つContainerServletを実装するサーブレットを作成する必要があります。 Tomcatはラッパーを設定するためにセッターに電話します。 Tomcat 5以降、これを使用していないので、メカニズムが変更されている可能性があります。 –

1

あなたのアプリケーションをserver.xmlのデフォルト仮想ホストに設定して、単一の仮想ホストが任意のホスト名宛ての要求に応答できるようにすることをお勧めします。 Tomcatは、localhostアプリケーションをデフォルトの仮想ホストとして設定して出荷されます。したがって、バニラのTomcatインストールのserver.xmlファイルを調べるだけで、これを行う方法がわかります。 ServletRequest.getServerName()メソッドを使用して、ユーザーが要求を送信したホスト名をプログラムで判断できます。

"host-manager"というWebアプリケーションと共に出荷されるTomcat。注:これはTomcatに付属している "manager" Webアプリケーションとは異なります。ホストマネージャは、サーバの再起動をせずに、構成の変更や新規仮想ホストの追加を行うことができました。 HTTP経由でホストマネージャーとやりとりすることができます(必要に応じてプログラマチックに)。しかし、server.xmlの変更をコミットしないという不幸な欠陥があったため、Webサーバーの再起動時にすべてが失われました。何らかの理由で、バージョン6から、Tomcatはホストマネージャーアプリケーションと一緒に出荷されなくなりました。それはもはやサポートされていないようです。

+0

こんにちはアサフ、あなたの答えのためにどうもありがとうございました! – jan

3

サーバー環境をプログラムで変更しないでください。これを行うための信頼できる標準的な方法はありません。最高のことは、ウェブアプリケーション側ですべてを行うことです。まず、Filterがこれに完全に適しています。アプリケーションスコープにキャッシュするデータベーステーブルまたはプロパティファイルのどこかに名前を格納します。 HttpServletRequest#getRequestURI()(またはpathinfoではなくサブドメインの場合はgetServerName())を確認し、それに応じて転送タスクを実行します。

これが役に立ちます。

+0

こんにちはBalusC、本当にあなたの答えをありがとう! – jan

+0

私はこれを行うための最良の方法だと思います。なぜDBマッピングが必要なのでしょうか? web-appを単にサブドメインにマップすることはできますか? – Sorter

3

使用JMX

ArrayList serverList = MBeanServerFactory.findMBeanServer(null); 
MBeanServer server = (MBeanServer) serverList.get(0); 
Object[] params = { "org.apache.catalina.core.StandardHost", hostName }; 
String[] signature = { "java.lang.String", "java.lang.String" }; 
server.invoke(new ObjectName("Catalina:type=Engine"), "addChild", params, signature); 

必要な場合は、それをホストオブジェクトと仕事を検索:

ObjectName host = new ObjectName("Catalina:type=Host,host=" + hostName); 
server.setAttribute(host, new Attribute("autoDeploy", false)); 
server.invoke(host, "start", null, null); 
+0

あなたの投稿をありがとう!あなたの投稿にシグネチャ/タグラインを使用しないでください。あなたのボックスはあなたの署名として数えられ、あなたのプロフィールを使って好きな自分に関する情報を投稿することができます。 [署名/タグラインに関するよくある質問](http://stackoverflow.com/faq#signatures) –

関連する問題