TomcatにWebアプリケーションがありますhttp://localhost:8080/WebApp/
私はApache 2(mod_proy)を構成して、ポートと名前を指定せずにlocalhostからWebアプリケーションに直接アクセスできるようにしました。例:http://localhost
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
Index.htmlはhttp://localhost
で正しく表示されます。しかし、サーブレットがリダイレクトする場合:
@WebServlet(description = "...", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
response.sendRedirect("a.html");
}
}
uRL http://localhost/login
を使用しています-http://localhost/WebApp/a.html
にリダイレクトされます
http://localhost/a.html
への正しいリダイレクトを取得するにはどうすればよいですか?
スチュアートとこのブログへのリンクのおかげで、解決策を見つけました: Apacheの背後にあるTomcat Webアプリケーションのリバースプロキシ
解決策:ProxyPreserveHostをオフにする必要があります!
理由:スイッチがオンになっている場合、プロキシバックエンドによって返される応答ヘッダーには、「localhost」またはポート番号(または80)のない実際のドメインが含まれます。そのため、ProxyPassReverseパターンは一致しません(ポートが異なるため、別のドメイン名が使用されている場合、ドメイン名も一致しません)。
構成:
<VirtualHost localhost:80>
ProxyPreserveHost Off
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
しかし、これはhttp経由でのみ機能し、ajp経由では機能しません(理由はわかりません)。それでもajpを使用したい場合は、次の回避策を使用できます-間違ったリダイレクトの後にApacheに別のリダイレクトを実行させます。
<VirtualHost localhost:80>
ProxyPass /WebApp !
ProxyPass / ajp://localhost:8009/WebApp/
ProxyPassReverse / ajp://localhost:8009/WebApp/
RedirectMatch 301 ^/WebApp/(.*)$ /$1
RedirectMatch 301 ^/WebApp$ /
</VirtualHost>
ProxyPass /WebApp !
ディレクティブは、mod_proxyでの以降の処理からパスを除外するために必要です(リダイレクトディレクティブの前にプロキシディレクティブが評価されるため)
次に、RedirectMatch
ディレクティブは、/WebApp/...
で始まるすべてのものを/WebApp
で先頭に/WebApp
のないURLにリダイレクトします。
唯一の欠点は、WebアプリケーションにWebApp
という名前のサブフォルダーを含めてはならないことです
私もこの問題を抱えていて、それに少し時間を費やしました。 Apache httpd構成を次のように変更すると、リダイレクトが機能すると信じています。
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /
</VirtualHost>
これは、Tomcat応答ヘッダーにプロキシヘッダーが含まれるためです(つまり、Locationヘッダーはhttp://localhost/WebApp
のではなく http://localhost:8080/WebApp
)ProxyPreserveHostがオンになっているためです。
脚注として:これは、webappsコンテキストを変更したい場合にも機能します。公開されているコンテキストを次のものを使用できるコンテキストに変更したいとします。
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass /context/ http://localhost:8080/WebApp/
ProxyPassReverse /context/ http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /context
</VirtualHost>
参考までに、このブログ投稿が非常に役立つことがわかりました: Apacheの背後にあるTomcat Webアプリケーションの逆プロキシ
リダイレクトの代わりに転送を使用
あなたの問題はsendRedirectの使用だと思います。 sendRedirectの呼び出しは、実際には、URLがリダイレクトされたことをブラウザーに示すことを前提としています。非表示にするには、転送を使用する必要があります。サーブレットでは、sendRedirectの代わりにこれを試してください。
String servletPath = request.getServletPath();
if(servletPath.equals("/app1")){
ServletContext ctx = request.getServletContext().getContext("/app1");
RequestDispatcher dispatcher=ctx.getServletContext().getRequestDispatcher( "/app1/app1.html" ); // or wherever you actually keep app1.html
dispatcher.forward( request, response );
}
Context.xml内でcrossContext = "true"を設定して、リクエストを他のWebアプリケーションに転送できるようにします。
<Context crossContext="true" ....../>
Apache2(ポート80で実行)要求をTomcat(ポート8080で実行されているアプリケーションサーバー)にリダイレクトしようとしたときに、同じ問題が発生しました。
これは完全に機能している設定です。
/etc/Apache2/sites-available/000-default.conf
に移動し、次の構成を追加します。
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual Host. For the default virtual Host (this file) this
# value is not decisive as it is used as a last resort Host regardless.
# However, you must set it for any further virtual Host explicitly.
#ServerName www.example.com
# for redirecting the websocket requests
ProxyPass /ws ws://localhost:7681/
#ProxyPass /ws ws://localhost:7681/
ProxyPassReverse /ws ws://localhost:7681/
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${Apache_LOG_DIR}/error.log
CustomLog ${Apache_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual Host. For example the
# following line enables the CGI configuration for this Host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# for redirecting the http request
ProxyPass /applicationContextUrl ' http://localhost:8080/applicationContextUrl
ProxyPassReverse /applicationContextUrl http://localhost:8080/applicationContextUrl
ProxyPassReverseCookiePath /applicationContextUrl /
ProxyPassReverseCookieDomain localhost applicationContextUrl
ProxyRequests off
ProxyTimeout 15
ErrorLog ${Apache_LOG_DIR}/nirad_error.log
LogLevel debug
CustomLog ${Apache_LOG_DIR}/nirad_access.log combined
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
#Require all denied
Require all granted
Require local
</Proxy>
</VirtualHost>
できました。端末に移動して、次のコマンドを実行します。
Sudo a2enmod proxy_http
(httpリダイレクト用)。Sudo a2enmod proxy_wstunnel
(WebSocketリダイレクト用)Sudo service Apache2 restart
apache2とTomcatを接続するためにAJPコネクターを使用する必要があります。これは、このための完璧なソリューションになります。
これを構成する方法が必要な場合は、この詳細を説明します