J'ai une application Web sur Tomcat http://localhost:8080/WebApp/
J'ai configuré Apache 2 (mod_proy) de sorte que l'application Web soit directement accessible par localhost avec le port et le nom out: e.g http://localhost
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
Le fichier index.html apparaît correctement sur http://localhost
. Mais si un servlet redirige:
@WebServlet(description = "...", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
response.sendRedirect("a.html");
}
}
et j'utilise l'URL http://localhost/login
- Je suis redirigé vers http://localhost/WebApp/a.html
Comment puis-je obtenir la redirection correcte vers http://localhost/a.html
?
Grâce à Stuart et à son lien vers ce blog, j'ai trouvé une solution: Proxy inverse des applications Web Tomcat derrière Apache
Solution: ProxyPreserveHost doit être désactivé!
Raison: s'il est activé, les en-têtes de réponse renvoyés par le serveur proxy contiendront "localhost" ou le domaine réel sans le numéro de port (ou 80). Ainsi, le modèle ProxyPassReverse ne correspond pas (en raison du port différent et si un autre nom de domaine est utilisé, le nom de domaine ne correspond pas non plus).
Config:
<VirtualHost localhost:80>
ProxyPreserveHost Off
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>
Mais cela ne fonctionne que via http, pas via ajp (je ne sais pas pourquoi). Si vous souhaitez toujours utiliser ajp, vous pouvez utiliser la solution de contournement suivante - Laissez Apache effectuer une autre redirection après la mauvaise redirection:
<VirtualHost localhost:80>
ProxyPass /WebApp !
ProxyPass / ajp://localhost:8009/WebApp/
ProxyPassReverse / ajp://localhost:8009/WebApp/
RedirectMatch 301 ^/WebApp/(.*)$ /$1
RedirectMatch 301 ^/WebApp$ /
</VirtualHost>
La directive ProxyPass /WebApp !
est nécessaire pour exclure le chemin d'accès du traitement ultérieur dans mod_proxy (car les directives proxy sont évaluées avant les directives de redirection)
Ensuite, les directives RedirectMatch
redirigent tout ce qui est écrit avec /WebApp/...
respectivement /WebApp
vers l'URL sans /WebApp
au début.
Le seul inconvénient est que vous ne devez pas avoir de sous-dossier nommé WebApp
dans votre application Web.
J'ai aussi eu ce problème et passé du temps dessus. Je crois que si vous modifiez votre configuration Apache httpd comme suit, votre redirection fonctionnera:
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass / http://localhost:8080/WebApp/
ProxyPassReverse / http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /
</VirtualHost>
Cela est dû au fait que les en-têtes de réponse Tomcat contiendront les en-têtes de proxy (c'est-à-dire que l'en-tête Location est http://localhost/WebApp
au lieu de http://localhost:8080/WebApp
) car ProxyPreserveHost est activé.
En tant que note de bas de page: Ceci fonctionne également avec vous souhaitez modifier le contexte de votre application Web. Supposons que vous souhaitiez modifier le contexte visible publiquement en contexte, vous pouvez utiliser les éléments suivants:
<VirtualHost localhost:80>
ProxyPreserveHost On
ProxyPass /context/ http://localhost:8080/WebApp/
ProxyPassReverse /context/ http://localhost/WebApp/
ProxyPassReverseCookiePath /WebApp /context
</VirtualHost>
Pour référence, cet article de blog m'a été extrêmement utile: Proxy inverse des applications Web Tomcat derrière Apache
Utilisez le transfert au lieu de la redirection
Je pense que votre problème est l'utilisation de sendRedirect. L'appel à sendRedirect est en fait supposé montrer au navigateur que l'URL a été redirigée. Si vous souhaitez masquer ce que vous devez utiliser le transfert. Dans votre servlet, essayez ceci au lieu de 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 );
}
Dans votre fichier context.xml, définissez crossContext = "true" pour pouvoir transférer les demandes vers d'autres applications Web.
<Context crossContext="true" ....../>
J'ai eu le même problème alors que j'essayais de rediriger la demande Apache2 (s'exécutant sur le port 80) à Tomcat (serveur d'applications s'exécutant sur le port 8080).
C'est la configuration qui fonctionne parfaitement.
Allez à /etc/Apache2/sites-available/000-default.conf
et ajoutez la configuration suivante:
<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>
Fait. Maintenant, allez au terminal et appuyez sur la commande suivante.
Sudo a2enmod proxy_http
(pour la redirection http).Sudo a2enmod proxy_wstunnel
(pour la redirection websocket)Sudo service Apache2 restart
vous avez utilisé AJP Connector pour connecter Apache2 et Tomcat, ce seront les solutions parfaites pour cela.
si vous avez besoin de savoir comment configurer cela, dites-moi que je vais expliquer ce détail