10

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

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

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

プログラムでいくつかのJavaメソッドを介してランタイムを追加する方法はありますか?

どうもありがとうございます!1月

4

5 に答える 5

8

Tomcatは、新しい仮想ホストを作成するためのAPIを提供します。これに必要なラッパーオブジェクトにアクセスするには、ContainerServletを実装する必要があります。このような仮想ホストを作成できます、

    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);

appBaseディレクトリが存在することを確認する必要があり、新しいホストをserver.xmlに永続化する方法を見つける必要があります。そうしないと、再起動時にホストが失われます。

ただし、このアプローチが機能することはめったにありません。ユーザーが独自のアプリを実行している場合は、Tomcatの個別のインスタンスを実行して、アプリをより適切にサンドボックス化できるようにする必要があります。たとえば、1つのアプリでメモリが不足しても、他のすべてのアプリが強制終了されるわけではありません。

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

于 2009-11-13T13:49:56.210 に答える
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);
于 2013-02-27T08:38:23.030 に答える
3

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

お役に立てれば。

于 2009-11-13T12:55:33.887 に答える
1

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

Tomcatには、「host-manager」と呼ばれるWebアプリケーションが付属していました。注:これは、Tomcatに引き続き付属している「マネージャー」Webアプリケーションとは異なります。ホストマネージャーは、サーバーを再起動せずに、構成を変更したり、新しい仮想ホストをその場で追加したりすることができました。HTTPを介してホストマネージャーと対話できます(必要に応じてプログラムで)。ただし、server.xmlへの変更をコミットしないという不幸な欠陥があったため、Webサーバーの再起動時にすべてが失われました。何らかの理由で、バージョン6以降、Tomcatにはhost-managerアプリケーションが付属しなくなりました。そのため、サポートされなくなったようです。

于 2009-11-13T12:55:16.070 に答える
1

ZZ Coder私をたくさん導いた答えを要約すると:

オブジェクトを取得するには、メソッドを実装ContainerServletしてオーバーライドするサーブレットを作成する必要があります。setWrapperorg.apache.catalina.Wrapper

そのためには、タグに含める必要があります。そうしないprivileged="true"context.xml Context、例外がスローされます。Wrapper次に、オブジェクトを使用して、次のことができます。

StandardContext context = (StandardContext) wrapper.getParent();
StandardHost currentHost = (StandardHost) context.getParent();
StandardEngine engine = (StandardEngine) currentHost.getParent();

StandardHost host = new StandardHost();
host.setAppBase(currentHost.getAppBase()); //in my case I created another instance of the same application
host.setDomain(currentHost.getDomain());
host.setAutoDeploy(false); // not restarting app whenever changes happen
host.setName("domain.com");
host.setThrowOnFailure(true);// tell it to throw an exception here if it fails to create the host
host.setDeployOnStartup(true);
host.setStartChildren(true);
host.setParent(engine); 
// you can add multiple aliases
host.addAlias(alias);

StandardContext ctx = new StandardContext();
ctx.setDocBase(context.getDocBase()); //again I reused my same application setting
ctx.setPath("");
if(currentHost.getWorkDir() != null)
{//create a working directory based on your new host's name
    ctx.setWorkDir(currentHost.getWorkDir().replace(currentHost.getName(), host.getName()));
}
ctx.setName(host.getDomain());

//some extra config that you can use
ctx.setUseHttpOnly(false);
ctx.setReloadable(false);
ctx.setXmlValidation(false);
ctx.setXmlNamespaceAware(false);
ctx.setCrossContext(false);
ctx.setParent(host);
// you have to have this or it will not work!!
ctx.addLifecycleListener(new ContextConfig()); 

//you can also create resources and add it to the context like so:
final ContextResource res = new ContextResource();
res.setName("name");
res.setAuth("Container");
res.setType("javax.sql.DataSource");
ctx.getNamingResources().addResource(res);

host.addChild(ctx);

engine.addChild(host);

を呼び出すことで、リソースにプロパティを追加できます。使用できるプロパティは次のres.setProperty("name", "value") とおり です。、、、、、、、、、、、、、、。initialSizemaxTotalmaxIdlemaxWaitMillisremoveAbandonedOnBorrowremoveAbandonedTimeoutvalidationQuerytimeBetweenEvictionRunsMillisdriverClassNameurlusernamepassword

もう1つのエキサイティングなことは、を呼び出して使用することでTomcatエンジンからホストを取得し、独自engine.findChild(domain)のTomcat管理パネルを用意することです。stop()start()getStateName()

于 2020-08-27T05:31:46.583 に答える