it-swarm.com.de

Vollständige URL und Abfragezeichenfolge in Servlet für HTTP- und HTTPS-Anforderungen abrufen

Ich schreibe einen Code, dessen Aufgabe darin besteht, eine angeforderte URL oder einen vollständigen Pfad abzurufen. Ich habe diesen Code geschrieben:

HttpServletRequest request;//obtained from other functions
String uri = request.getRequestURI();
if (request.getQueryString() != null)
    uri += "?" + request.getQueryString();

Wenn ich also http://google.com?q=abc Durchsuche, ist es in Ordnung (richtig). Aber es gibt ein Problem beim Durchsuchen von https://google.com. Der Wert von uri ist http://google.com:443google.com:443. Das Programm funktioniert also nicht nur, wenn HTTPS verwendet wird.

Und die Ausgabe ist dieselbe für request.getRequestURL().toString().

Was ist die Lösung?

72
progrrammer

Standardmäßig gibt getRequestURL() die vollständige URL an, wobei nur die Abfragezeichenfolge fehlt.

In HttpServletRequest können Sie mithilfe der folgenden Methoden einzelne Teile des URI abrufen:

// 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() gibt Ihnen "https", wenn es sich um eine https://domain - Anfrage handelte.
  • .getServerName() ergibt domain für http(s)://domain.
  • .getServerPort() gibt Ihnen den Port.

Verwenden Sie das folgende Snippet:

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() : "");

Dieses Snippet oben zeigt den vollständigen URI an, wobei der Port ausgeblendet wird, wenn der Standard-URI verwendet wurde, und ohne das Hinzufügen von "?" Und der Abfragezeichenfolge, wenn dieser nicht angegeben wurde.


Proxy-Anfragen

Beachten Sie, dass Sie sich den Header X-Forwarded-Proto Ansehen müssen, wenn Ihre Anforderung einen Proxy durchläuft, da das Schema möglicherweise geändert wird:

request.getHeader("X-Forwarded-Proto")

Ein üblicher Header ist auch X-Forwarded-For, Der die ursprüngliche Anforderungs-IP anstelle der IP des Proxys anzeigt.

request.getHeader("X-Forwarded-For")

Wenn Sie selbst für die Konfiguration des Proxys/Load Balancers verantwortlich sind, müssen Sie sicherstellen, dass diese Header beim Weiterleiten festgelegt werden.

152
acdcjunior

Verwenden Sie einfach:

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

Die Tatsache, dass eine HTTPS -Anforderung zu HTTP wird, als Sie versuchten, die URL auf der Serverseite zu erstellen, weist darauf hin, dass Sie möglicherweise einen Proxy/Load Balancer (nginx, pound, etc.) Verschieben der SSL-Verschlüsselung vor und nach Ihrem Back-End-Service in normalem HTTP.

Wenn dies der Fall ist, überprüfen Sie,

  1. ob Ihr Proxy so eingerichtet wurde, dass Header korrekt weitergeleitet werden (Host, X-forwarded-proto, X-forwarded-for usw.).
  2. ob Ihr Dienstcontainer (z. B. Tomcat) so eingerichtet ist, dass der vordere Proxy erkannt wird. Zum Beispiel erfordert Tomcat das Hinzufügen von secure="true" scheme="https" proxyPort="443" - Attributen zu seinem Connector
  3. ob Ihr Code oder Dienstcontainer die Header korrekt verarbeitet. Beispielsweise ersetzt Tomcat automatisch scheme-, remoteAddr- usw. Werte, wenn Sie RemoteIpValve zu seinem Engine hinzufügen. (Siehe Konfigurationsanleitung , JavaDoc ), damit Sie diese Header in Ihrem Code nicht manuell verarbeiten müssen.

Falsche Proxy-Header-Werte können zu einer falschen Ausgabe führen, wenn request.getRequestURI() oder request.getRequestURL() versucht, die ursprüngliche URL zu erstellen.

1
dancnfoo