Pobierz pełny adres URL i ciąg zapytania w Servlet dla żądań HTTP i HTTPS

Piszę kod, którego zadaniem jest odzyskanie żądanego adresu URL lub pełnej ścieżki. Napisałem ten kod:

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

Więc kiedy przeglądam {[1] } jest OK (poprawne). Ale jest problem, gdy przeglądam https://google.com. Wartość uri to http://google.com:443google.com:443, więc program nie tylko wtedy, gdy jest używany HTTPS.

I wyjście jest takie samo dla request.getRequestURL().toString().

Jakie jest rozwiązanie?

Author: divanov, 2013-05-21

4 answers

Według projektu, getRequestURL() daje pełny adres URL, brakuje tylko ciągu zapytania.

W HttpServletRequest, można uzyskać poszczególne części URI za pomocą poniższych metod:

// 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() da ci "https" jeśli to była https://domain Prośba.
  • .getServerName() daje domain na http(s)://domain.
  • .getServerPort() da ci port.

Użyj poniższego fragmentu:

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

Ten fragment powyżej otrzyma pełny URI, ukrywając port, jeśli domyślny był używane, a nie dodawanie "?" I ciągu zapytania, jeśli ten ostatni nie został podany.


Proxied requests

Zauważ, że jeśli twoje żądanie przechodzi przez proxy, musisz spojrzeć na nagłówek X-Forwarded-Proto, ponieważ schemat może zostać zmieniony:

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

Również wspólny nagłówek to X-Forwarded-For, który pokazuje oryginalny adres IP żądania zamiast adresu proxys.

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

Jeśli sam jesteś odpowiedzialny za konfigurację proxy/load balancer, musisz upewnić się, że te nagłówki są ustawiane podczas przekazywania.

 169
Author: acdcjunior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Po Prostu Użyj:

String Uri = request.getRequestURL()+"?"+request.getQueryString();
 9
Author: sumitkanoje,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Fakt, że żądanie HTTPS staje się HTTP podczas próby zbudowania adresu URL po stronie serwera wskazuje, że możesz mieć równoważnik proxy/load balancer (nginx, pound, itd.) odciążenie szyfrowania SSL z przodu i z przodu do usługi zaplecza w zwykły HTTP.

Jeśli tak jest, sprawdź,

  1. czy serwer proxy został skonfigurowany do prawidłowego przesyłania nagłówków(Host, X-forwarded-proto, X-forwarded-for, itp.).
  2. czy twój kontener Usług (np. Tomcat) jest skonfigurowany do rozpoznawania proxy z przodu. Na przykład, Tomcat wymaga dodania atrybutów secure="true" scheme="https" proxyPort="443" do swojego Connector
  3. czy Twój kod lub kontener usług przetwarza poprawnie nagłówki. Na przykład Tomcat automatycznie zastępuje scheme, remoteAddr, itd. wartości po dodaniu RemoteIpValve do jego Engine. (zobacz Przewodnik Konfiguracji, JavaDoc ), więc nie musisz ręcznie przetwarzać tych nagłówków w kodzie.

Nieprawidłowe wartości nagłówka proxy mogą spowodować nieprawidłowe wyjście, gdy request.getRequestURI() lub request.getRequestURL() próbuje skonstruować pochodzący adres URL.

 3
Author: dancnfoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-05 23:39:16

Wiem, że to jest pytanie Javy, ale jeśli używasz Kotlina, możesz to zrobić całkiem ładnie:

val uri = request.run {
    if (queryString.isNullOrBlank()) requestURI else "$requestURI?$queryString"
}
 0
Author: Adam Millerchip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-10 05:21:07