wake-up-neo.com

So erhalten Sie den Hostnamen mit dem Port aus einer http- oder https-Anforderung

Ich habe zwei Anwendungen in JBoss-Container (gleiche Unix-Box) bereitgestellt. Wenn ich eine Anfrage von app1 bekomme, muss ich eine entsprechende Anfrage für app2 erstellen.

z.B:
Wenn die Anforderung von app1 lautet: http://example.com/context?param1=123
dann muss ich " http://example.com/ " extrahieren, damit ich die zweite app anfordern kann.

Ich habe versucht mit:

  HttpServletRequest.getServerName() & 
  HttpServletRequest.getServerPort() & \
  HttpServletRequest.getHeader("Host") 

methoden, aber die Anfrage kann von http oder https sein.

Bitte lassen Sie mich wissen, ob es einen anderen besseren Weg gibt.

23
kumar

Sie können HttpServletRequest.getScheme() verwenden, um entweder "http" oder "https" abzurufen.

Die Verwendung zusammen mit HttpServletRequest.getServerName() sollte ausreichen, um den benötigten Teil der URL neu zu erstellen.

Sie müssen den Port nicht explizit in der URL angeben, wenn Sie die Standardports verwenden (80 für http und 443 für https).

Edit: Wenn sich Ihr Servlet-Container hinter einem Reverse-Proxy oder Load-Balancer befindet, der das SSL abbricht, ist dies etwas komplizierter, da die Anforderungen als einfacher http an den Servlet-Container weitergeleitet werden. Sie haben einige Möglichkeiten:

1) Verwenden Sie stattdessen HttpServletRequest.getHeader("x-forwarded-proto"); Dies funktioniert nur, wenn Ihr Lastenausgleich den Header richtig setzt (Apache sollte afaik sein).

2) Konfigurieren Sie ein RemoteIpValve in JBoss/Tomcat, damit getScheme() wie erwartet funktioniert. Auch dies funktioniert nur, wenn der Lastenausgleich die richtigen Header setzt.

3) Wenn dies nicht funktioniert, können Sie in Tomcat/JBoss zwei verschiedene Connectors konfigurieren, einen für http und einen für https, wie in diesem Artikel beschrieben.

40
David Levesque

Sie können HttpServletRequest.getRequestURL und HttpServletRequest.getRequestURI verwenden.

StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
String Host = url.substring(0, url.indexOf(uri)); //result
16
jtahlborn

Wenn Sie den Lastenausgleich & Nginx verwenden, konfigurieren Sie sie, ohne den Code zu ändern.

Nginx:

proxy_set_header       Host $Host;  
proxy_set_header  X-Real-IP  $remote_addr;  
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;  
proxy_set_header X-Forwarded-Proto  $scheme;  

Server.xml-Engine von Tomcat:

<Valve className="org.Apache.catalina.valves.RemoteIpValve"  
remoteIpHeader="X-Forwarded-For"  
protocolHeader="X-Forwarded-Proto"  
protocolHeaderHttpsValue="https"/> 

Wenn Sie nur die Nginx-Konfigurationsdatei ändern, sollte der Java-Code Folgendes sein:

String XForwardedProto = request.getHeader("X-Forwarded-Proto");
3
W.Hao

Wenn Sie die ursprüngliche URL verwenden möchten, verwenden Sie einfach die von jthalborn ..__ beschriebene Methode. Wenn Sie die URL neu erstellen möchten, wie es von David Levesque erklärt wurde, hier ein Codeausschnitt dafür:

final javax.servlet.http.HttpServletRequest req = (javax.servlet.http.HttpServletRequest) ...;
final int serverPort = req.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
  // No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
  url = String.format("%s://%s/...", req.getScheme(), req.getServerName(), ...);
} else {
  url = String.format("%s://%s:%s...", req.getScheme(), req.getServerName(), serverPort, ...);
}

Sie müssen immer noch den Fall eines Reverse-Proxy berücksichtigen:

Konnte Konstanten für die Ports verwenden, aber nicht sicher, ob es eine zuverlässige Quelle für sie gibt, Standardports:

Die meisten Entwickler wissen ohnehin über Port 80 und 443, daher sind Konstanten nicht so hilfreich.

Siehe auch dieses ähnliche post .

3

Siehe http://docs.Oracle.com/javase/tutorial/networking/urls/urlInfo.html . Dies ist die prägnanteste Berichterstattung zum URL-Parsing. 

1
Satyajit Paul

Ich bin zu spät zur Party, aber ich hatte das gleiche Problem mit Java 8.

Das hat bei mir mit dem Objekt HttpServletRequest request Funktioniert.

request.getHeader("Origin");

und

request.getHeader("referer");

Wie ich zu diesem Schluss kam:

Ich habe eine Java App, die auf http: // localhost: 30 läuft HTTP-Post zu einer anderen Java App, auf der ich ausgeführt habe http: // localhost: 808.

Aus dem Java Code, der auf http: // localhost: 808 ausgeführt wird, konnte ich nicht ' t den http: // localhost: 30 aus dem HttpServletRequest mit den obigen Antworten Für mich hat die Verwendung der getHeader -Methode mit der richtigen Zeichenfolge-Eingabe funktioniert.

request.getHeader("Origin") hat mir " http: // localhost: 30 " gegeben, was ich wollte.

request.getHeader("referer") hat mir " http: // localhost: 3000/xxxx " gegeben, wobei xxxx die vollständige URL ist Ich habe von der anfragenden App.

0

Wenn Ihr Server hinter einem Proxyserver ausgeführt wird, stellen Sie sicher, dass der Proxy-Header festgelegt ist:

proxy_set_header X-Forwarded-Proto  $scheme;

Um den richtigen scheme & url zu erhalten, können Sie die Klassen von springframework verwenden:

public String getUrl(HttpServletRequest request) {
    HttpRequest httpRequest = new ServletServerHttpRequest(request);
    UriComponents uriComponents = UriComponentsBuilder.fromHttpRequest(httpRequest).build();

    String scheme = uriComponents.getScheme();             // http / https
    String serverName = request.getServerName();     // hostname.com
    int serverPort = request.getServerPort();        // 80
    String contextPath = request.getContextPath();   // /app

    // Reconstruct original requesting URL
    StringBuilder url = new StringBuilder();
    url.append(scheme).append("://");
    url.append(serverName);

    if (serverPort != 80 && serverPort != 443) {
        url.append(":").append(serverPort);
    }
    url.append(contextPath);
    return url.toString();
}
0
Mamun Sardar