J'écris un code dont la tâche consiste à récupérer une URL demandée ou un chemin complet. J'ai écrit ce code:
HttpServletRequest request;//obtained from other functions
String uri = request.getRequestURI();
if (request.getQueryString() != null)
uri += "?" + request.getQueryString();
Donc, quand je navigue sur http://google.com?q=abc
c'est OK (correct). Mais il y a un problème lorsque je navigue sur https://google.com
. La valeur de uri
est http://google.com:443google.com:443
, le programme ne le fait donc pas uniquement lorsque HTTPS
est utilisé.
Et le résultat est le même pour request.getRequestURL().toString()
.
Quelle est la solution?
De par sa conception, getRequestURL()
vous donne l'URL complète, il ne manque que la chaîne de requête.
Dans HttpServletRequest
, vous pouvez obtenir des parties individuelles de l'URI en utilisant les méthodes ci-dessous:
// Example: http://myhost:8080/people?lastname=Fox&age=30
String uri = request.getScheme() + "://" + // "http" + "://
request.getServerName() + // "myhost"
":" + // ":"
request.getServerPort() + // "8080"
request.getRequestURI() + // "/people"
"?" + // "?"
request.getQueryString(); // "lastname=Fox&age=30"
.getScheme()
vous donnera "https"
s'il s'agissait d'une demande https://domain
..getServerName()
donne domain
sur http(s)://domain
..getServerPort()
vous donnera le port.String uri = request.getScheme() + "://" +
request.getServerName() +
("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) +
request.getRequestURI() +
(request.getQueryString() != null ? "?" + request.getQueryString() : "");
L'extrait ci-dessus obtiendra l'URI complet, en masquant le port si celui par défaut a été utilisé, sans ajouter le "?"
et la chaîne de requête si ce dernier n'a pas été fourni.
Notez que si votre demande passe par un proxy, vous devez regarder l’en-tête X-Forwarded-Proto
car le schéma peut être modifié:
request.getHeader("X-Forwarded-Proto")
En outre, un en-tête commun est X-Forwarded-For
, qui affiche l'adresse IP de la demande d'origine au lieu de l'adresse IP du proxy.
request.getHeader("X-Forwarded-For")
Si vous êtes responsable de la configuration de l'équilibreur proxy/charge, vous devez vous assurer que ces en-têtes sont définis lors du transfert.
String Uri = request.getRequestURL()+"?"+request.getQueryString();
Le fait qu'une demande HTTPS
devienne HTTP
lorsque vous tentez de créer l'URL côté serveur indique que vous pourriez avoir un équilibreur proxy/charge (nginx
, pound
, etc. .) décharger le cryptage SSL avant et le transférer à votre service principal en clair HTTP
.
Si c'est le cas, vérifiez,
Host
, X-forwarded-proto
, X-forwarded-for
, etc.).Tomcat
) est configuré pour reconnaître le proxy précédent. Par exemple, Tomcat
nécessite l'ajout d'attributs secure="true" scheme="https" proxyPort="443"
à sa Connector
Tomcat
remplace automatiquement les valeurs de scheme
, remoteAddr
, etc. lorsque vous ajoutez RemoteIpValve
à sa Engine
. (voir Guide de configuration , JavaDoc ) afin que vous n'ayez pas à traiter ces en-têtes manuellement dans votre code.Des valeurs d'en-tête de proxy incorrectes pourraient entraîner une sortie incorrecte lorsque request.getRequestURI()
ou request.getRequestURL()
tente de construire l'URL d'origine.