Ich schreibe einen Code, dessen Aufgabe es ist, 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 surfe http://google.com?q=abc
, ist es OK (richtig). Aber es gibt ein Problem beim Stöbern https://google.com
. Der Wert von uri
ist http://google.com:443google.com:443
, also das Programm nicht nur, wenn HTTPS
es verwendet wird.
Und die Ausgabe ist die gleiche für request.getRequestURL().toString()
.
Was ist die Lösung?
java
servlets
httprequest
Programmierer
quelle
quelle
HttpServletRequest
diese falsch konstruieren. Vielleicht können Sie eine SSCCE erstellen , die das genaue Problem demonstriert?Antworten:
Mit dem Design,
getRequestURL()
gibt Ihnen die vollständige URL, nur die Abfragezeichenfolge fehlt.In
HttpServletRequest
können Sie einzelne Teile des URI mit den folgenden Methoden 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()
wird Ihnen geben,"https"
wenn es einehttps://domain
Anfrage war..getServerName()
gibtdomain
aufhttp(s)://domain
..getServerPort()
wird Ihnen den Hafen geben.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() : "");
In diesem obigen Snippet wird der vollständige URI abgerufen, wobei der Port ausgeblendet wird, wenn der Standard-URI verwendet wurde, und der
"?"
und die Abfragezeichenfolge nicht hinzugefügt werden, wenn letzterer nicht angegeben wurde.Proxied Anfragen
Beachten Sie, dass Sie sich den
X-Forwarded-Proto
Header ansehen müssen, wenn Ihre Anforderung einen Proxy durchläuft, da das Schema möglicherweise geändert wird:request.getHeader("X-Forwarded-Proto")
Es gibt auch einen allgemeinen Header
X-Forwarded-For
, der die ursprüngliche Anforderungs-IP anstelle der Proxy-IP anzeigt.request.getHeader("X-Forwarded-For")
Wenn Sie selbst für die Konfiguration des Proxy- / Load-Balancers verantwortlich sind, müssen Sie sicherstellen, dass diese Header bei der Weiterleitung festgelegt werden.
quelle
https
aber mit Fehler. Es gibt keine Abfrage - String inhttps
getRequestURL()
muss funktionieren . Scheint, als ob du etwas falsch machst ...google.com:443
zweimal bekommen . Außerdem sehe ich dort http statt https ...getScheme()
in einergetServerName()
in der anderen) drucken. Was ist das Ergebnis? Dies gibt Ihnen einen Hinweis darauf, was der problematische Teil ist.Einfach verwenden:
String Uri = request.getRequestURL()+"?"+request.getQueryString();
quelle
getRequestURL
dies auf einer Fehlerseite nicht funktioniert. Wenn Sie also eine404.jsp
und z. B. eine Umleitung durchführen müssen, müssen Sie den Import hinzufügen:<%@ page import="org.apache.catalina.util.RequestUtil" %>
und verwendenString requestedLocation = RequestUtil.filter((String) request.getAttribute("javax.servlet.error.request_uri"));
Die Tatsache , dass eine
HTTPS
Anfrage wird ,HTTP
wenn man versucht , die URL auf Server - Seite zu konstruieren , zeigt an, dass Sie einen Proxy / Load - Balancer haben könnte (nginx
,pound
usw.) Offloading SSL - Verschlüsselung vor und freuen uns auf Ihren Back - End - Service in EbeneHTTP
.Wenn dies der Fall ist, überprüfen Sie,
Host
,X-forwarded-proto
,X-forwarded-for
, usw.).Tomcat
) so eingerichtet ist, dass er den Proxy vor sich erkennt. Zum BeispielTomcat
erfordert das Hinzufügen vonsecure="true" scheme="https" proxyPort="443"
Attributen zu seinerConnector
Tomcat
ersetzt automatischscheme
,remoteAddr
usw. Werte , wenn Sie hinzufügen ,RemoteIpValve
um seineEngine
. (siehe Konfigurationshandbuch , JavaDoc ), damit Sie diese Header in Ihrem Code nicht manuell verarbeiten müssen.Falsche Proxy Headerwerte in falscher Ausgabe führen, wenn
request.getRequestURI()
oderrequest.getRequestURL()
Versuche , den Ursprung URL zu konstruieren.quelle
Ich weiß, dass dies eine Java-Frage ist, aber wenn Sie Kotlin verwenden, können Sie dies ganz gut tun:
val uri = request.run { if (queryString.isNullOrBlank()) requestURI else "$requestURI?$queryString" }
quelle