7

ローカルマシンでTomcat6インスタンスを実行しています。

構成に次の変更を加えました。

  • / conf /内context.xml–タグを次のように変更しました

    <Context crossContext="true">
    
  • / conf /内server.xml –タグを次のように変更しました

    <Connector port="8080" protocol="HTTP/1.1" emptySessionPath="true"
           connectionTimeout="20000" 
           redirectPort="8443" />
    

ここにデプロイされた名前のWARファイルがあり、SampleProject.warフォルダーに抽出するとしますSampleProject

このWARの一部のサーブレットでは、たとえばSampleServlet、次のように2つのコードブロックを記述します。

ServletContext context1 = session.getServletContext();

ServletContext context2 = session.getServletContext().getContext("/SampleProject");

context1との違いは何context2ですか?どちらもアプリケーションのコンテキストを参照していると思いました。しかし、にいくつかの属性を設定し、にcontext1アクセスするとcontext2、の値を取得できませんcontext2

どんな助けでもいただければ幸いです。

4

3 に答える 3

5

あなたの質問は少し誤解されていて、APIの基本的な理解はすでにあると思います。つまり、Webアプリが設定されると、サーバーにデプロイされた他のWebアプリに対応するコンテキストにアクセスするためにcrossContext="true"使用できるようになります。getContext()

getServletContext().getContext() equals NULL unless <Context crossContext="true">

私が理解したことから、あなたの質問は実際には/SameWebAppなぜですか

ServletContext context1 = session.getServletContext();
context1.setAttribute("contextAttribute", new Object());
ServletContext context2 = session.getServletContext().getContext("/SameWebApp");

System.out.println(context1.equals(context2)); // prints false, or 
System.out.println(context2.getAttribute("contextAttribute")); // prints null (at least they could have been clones)

一言で言えば、答えは「セキュリティ」です。「adminEmail」コンテキスト属性が、そのを持つ邪悪なWebアプリによって改ざんされていないことを保証できない場合を想像してみてくださいcrossContext=true。「パスワードを忘れた場合」のリクエストが届くとすぐに、アプリが自分自身を危険にさらす可能性があります。:)

Tomcatの内部に飛び込む

Tomcat 7は、class ApplicationContext implements ServletContextとしてから戻るを提供しgetContext("/context-root")ます

    if (context.getCrossContext()) {
        // If crossContext is enabled, can always return the context
        return child.getServletContext();
    } else if (child == context) {
        // Can still return the current context
        return context.getServletContext();
    } else {
        // Nothing to return
        return (null);
    }

contextこれは現在のWebアプリに属しchild、他のWebアプリを表します。しかし、待ってください、Tomcatがそれを子と呼ぶ理由は何ですか?

これら2つは実際にはクラスApplicationContextのインスタンスではありませんが、サーブレット固有のものではなく、crossContext、hostname、mimeMappingsなどのWebアプリのTomcat固有の構成設定を保持するため、上記の子と呼ばれています。。StandardContextimplements ContextStandardContext.getParent()Container

とにかく、child == contexttrueの場合、つまりgetContext()「/ SameWebApp」で呼び出された場合に関心があります。の別のインスタンスStandardContext.getServletContext()返すように実装された呼び出しが委任されています。ApplicationContext

context1これが、設定した属性がに見つからない理由ですcontext2

しかし、待ってください、それにはもう少しあります。なぜStandardContext.getServletContext()のように戻るのですか

return (context.getFacade());

Tomcatインスタンスは、基本的に2種類のJavaコードを実行しています。

  • 提供されるコンテナ、および
  • ユーザーがデプロイされました

コンテナコードは「信頼できる」ものであり、昇格された特権で実行する必要がある場合があります。一方、ユーザーコードは信頼されておらず、Tomcatの内部を危険にさらすことを制限する必要があります。

これを実現するためにTomcatが行うことの1つは、常に(したがって)をラップApplicationContextFacadeアラウンドすることです。要約すると、単純な実装のように見えるのは、実際にはにマップされており、はにラップされています。ApplicationContextStandardContextServletContextStandardContextApplicationContextApplicationContextFacade

ApplicationContextFacadeReflectionGlobals.IS_SECURITY_ENABLEDSecurityUtil.isPackageProtectionEnabled()設定を組み合わせて使用​​する動作の詳細については、サーブレットがSOのファサードを介してTomcatApplicationContextにアクセスする理由を参照してください。

参照:
Tomcat 7ソースコード(ダウンロードリンク)

于 2013-05-02T20:26:57.313 に答える
3

絶対に、これら2つのコンテキストオブジェクトは別のオブジェクトとは異なります。Context1オブジェクトは、現在のWebアプリケーションサーブレットコンテキストobjを提供します。(ServletContext context1 = session.getServletContext();)

context2オブジェクトは、指定されたWebアプリケーションのservletcontext objを提供します(ServletContext context2 = session.getServletContext()。getContext( "/ SampleProject");)

あるコンテキストでオブジェクトを設定し、別のコンテキストを使用して取得しようとしているため、現在のアプリケーションコンテキストに配置して、別のWebアプリケーションコンテキストから属性を取得することはできません。ただし、2番目の方法を使用すると、属性を別のWebアプリケーションコンテキストに常駐させることができます。

于 2013-04-06T03:14:28.890 に答える
3

オブジェクト指向とJavaEEプラットフォームの標準+セキュリティを考えてください。

最初の呼び出しは、現在のアプリの最終的なサーブレットコンテキストを返し、すべての操作がサポートされます。

2番目の呼び出しは、任意のアプリに使用できるサーブレットコンテキストのコピーを返します。javadocで(漠然と!)述べられているように、その目的は、を取得できるようにすることRequestDispatcherです。これにより、他のアプリのページにディスパッチできます。他の主要ですが暗黙の要件は、これを安全に実行し、アプリ間でセッション状態またはサーブレットコンテキストを共有できないJavaEE仕様を尊重することです。「不正なアプリB」が「良いアプリA」にブルートフォースでサーブレットコンテキストデータを変更(または読み取り)するだけで、ひどいダメージを与える可能性があると想像してみてください。それがコピーである理由です。

したがって、コピーに属性を設定しても、元の属性は変更されません。コピーは「サポートされていない操作の例外」をスローする必要があると主張することができます。または、getRequestDispatcherを別のクラスにリファクタリングするか、App Context URLを渡すことができるようにする必要があると主張することもできます。...しかし、残念ながら、これらのことはどちらも当てはまりません。B ^)

于 2013-05-02T05:12:05.420 に答える