web-dev-qa-db-fra.com

Obtention de l'URL complète et de la chaîne de requête dans Servlet pour les requêtes HTTP et HTTPS

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?

72
progrrammer

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.

Utilisez l'extrait ci-dessous:

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.


Requêtes sollicitées

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.

152
acdcjunior

Utilisez simplement:

String Uri = request.getRequestURL()+"?"+request.getQueryString();
10
sumitkanoje

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,

  1. si votre proxy a été configuré pour transférer correctement les en-têtes (Host, X-forwarded-proto, X-forwarded-for, etc.).
  2. si votre conteneur de service (par exemple, 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
  3. que votre code ou votre conteneur de service traite correctement les en-têtes. Par exemple, 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.

1
dancnfoo