0

RedirectAttributes の flashAttributes を機能させようとしているときに問題が発生しました。Tomcat 7.0 で Spring MVC を使用して構築された Web サイトと、Apache mod_proxy および ajp を使用するリバース プロキシをセットアップしました。

私が直面している問題はこの質問でも説明されていますが、そこに記載されている回答は私の場合には当てはまりません (Tomcat の単一インスタンスを使用しています)。

これは、テスト目的で使用しているコントローラーのスニペットです。

@RequestMapping(value = "/land", method = RequestMethod.GET)
    public String land(RedirectAttributes redirectAttrs, Model model) {
    return "redirect_landing";
}

@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect(RedirectAttributes redirectAttrs, HttpSession session) {

    // add a session message
    session.setAttribute("sessionMessage", "a session message");

    // add a flash message
    redirectAttrs.addFlashAttribute("flashMessage", "a flash message");

    // define the base url
    String baseUrl = "http://localhost:8080/MyApp/";
    // String baseUrl = "http://dev.myapp.lan/";

    return "redirect:" + baseUrl + "land";
}

テンプレートは次のようにシンプルです。

Flash message: ${flashMessage}
Session message: ${sessionMessage}

Web サイトに Tomcat で直接アクセスしているか、Apache リバース プロキシ経由でアクセスしているかによって、同じコードでも異なる結果が得られます。

Tomcat の応答:
フラッシュ メッセージ: フラッシュ メッセージ
セッション メッセージ: セッション メッセージ

Apache mod_proxy の背後:
Flash メッセージ:
セッション メッセージ: セッション メッセージ

プロキシ経由で Web サイトにアクセスすると、フラッシュ メッセージが表示されないのはなぜですか?

RedirectAttributesModelMap.javaModelMap.javaのコードをチェックアウトしましたが、そこには十分な情報がありません (明らかに、ロジックは別の場所で実装されています)。

注: 目標を達成するために、いつでもセッション属性にフォールバックできますが、この問題は、リバース プロキシの背後で Tomcat を使用する人にとっては十分に興味深いものです。


プロキシ構成 (スニペット):

<VirtualHost *:80>
    ServerName dev.myapp.lan    

    ProxyPass / ajp://localhost:8009/MyApp/

    ProxyPassReverseCookiePath /MyApp /
    ProxyPassReverseCookieDomain localhost MyApp

    ErrorLog /var/log/apache2/phonebook-error.log
    LogLevel warn

    CustomLog /var/log/apache2/phonebook-access.log combined
</VirtualHost> 

ティア。

4

2 に答える 2

2

リバース プロキシでコンテキスト パスを変更すると、多くの場合、問題が発生します。これが問題であると仮定すると、2 つの選択肢があります。

  1. MyApp.war の名前を ROOT.war (または MyApp ディレクトリがディレクトリの場合は ROOT ) に変更して、アプリケーションを Tomcat の ROOT アプリケーションとしてデプロイします。

  2. 適切なツールを起動して HTTP ヘッダーとコンテンツ (Wireshark、FireBug、ieHttpHeaders など - あなたとあなたの環境に適したものを選んでください) を調べ、パスを変更する必要があり、まだ変更されていないすべての場所を見つけます。 . mod_headers と mod_substitute (または同等のもの) を使用して、リバース プロキシで必要な変更を行います。

個人的には、私は常に 1 を選択します。これは、より単純で、より速く、より簡単で、エラーが発生しにくいためです。お客様がリバース プロキシのコンテキスト パスを変更する必要があると主張した場合、問題のデバッグを支援するために何日も費やしてきました。

なぜこれが起こるのですか?

リバース プロキシでコンテキスト パスが変更された場合、そのパスを変更する必要がある場所が多数あります。

  1. ユーザー エージェントから受け取ったリクエスト URL
  2. バックエンド サーバーによって返されるリダイレクトの場所
  3. Web ページ内のリンクの URL
  4. アプリケーション (またはアプリケーションが使用しているライブラリ) によって設定されたカスタム HTTP 応答ヘッダー
  5. Cookie パス

ProxyPass ハンドル 1

ProxyPassReverse は Location、Content-Location、および URI ヘッダーを処理します (2)

ProxyPassReverseCookiePath は 5 を処理します

mod_proxy は、ケース 4 またはケース 5 を正しく処理するのが難しいため、処理しません。必要な結果を得るには、ケースバイケースで非常に慎重な正規表現を作成する必要があります。

flashAttributes がパスを含むカスタム HTTP ヘッダーを使用していると思われるため、機能しません。セッションは、通常はセッション Cookie によって管理され、ProxyPassReverseCookiePath が構成されているため、機能します。

于 2013-10-14T21:00:31.873 に答える