web-dev-qa-db-fra.com

Comment obtenir le nom d'hôte avec le port à partir d'une requête http ou https

J'ai deux applications déployées dans le conteneur jboss (même boîte unix). Si je reçois une demande de app1, je dois encadrer une demande correspondante pour app2.

par exemple:
si la requête app1 est: http://example.com/context?param1=123
alors je dois extraire " http://example.com/ ", afin de pouvoir cadrer la demande pour la deuxième application.

J'ai essayé d'utiliser:

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

méthodes, mais la requête peut être de type http ou https.

S'il vous plaît laissez-moi savoir s'il y a une autre meilleure façon . Merci!

23
kumar

Vous pouvez utiliser HttpServletRequest.getScheme() pour récupérer "http" ou "https".

Son utilisation avec HttpServletRequest.getServerName() devrait suffire à reconstruire la partie de l'URL dont vous avez besoin.

Vous n'avez pas besoin de mettre explicitement le port dans l'URL si vous utilisez les ports standard (80 pour http et 443 pour https).

Edit: si votre conteneur de servlets se trouve derrière un proxy inverse ou un équilibreur de charge qui termine le protocole SSL, la procédure est un peu plus délicate car les demandes sont transférées au conteneur de servlets au format http. Vous avez quelques options:

1) Utilisez HttpServletRequest.getHeader("x-forwarded-proto") à la place; cela ne fonctionne que si votre équilibreur de charge définit l'en-tête correctement (Apache devrait toujours être connu).

2) Configurez un RemoteIpValve dans JBoss/Tomcat qui permettra à getScheme() de fonctionner comme prévu. Là encore, cela ne fonctionnera que si l’équilibreur de charge définit les en-têtes appropriés.

3) Si ceci ne fonctionne pas, vous pouvez configurer deux connecteurs différents dans Tomcat/JBoss, un pour http et un pour https, comme décrit dans cet article .

40
David Levesque

Vous pouvez utiliser HttpServletRequest.getRequestURL et HttpServletRequest.getRequestURI .

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

Si vous utilisez l'équilibreur de charge et Nginx, configurez-les sans modifier le code.

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;  

Moteur server.xml de Tomcat:

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

Si vous ne modifiez que le fichier de configuration Nginx, le code Java doit être:

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

Si vous voulez l'URL d'origine, utilisez simplement la méthode décrite par jthalborn . Si vous voulez reconstruire l'URL comme le disait David Levesque, voici un extrait de code:

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, ...);
}

Vous devez toujours considérer le cas d'un proxy inverse:

Peut utiliser des constantes pour les ports mais ne sait pas s'il existe une source fiable pour eux, ports par défaut:

La plupart des développeurs connaissent de toute façon les ports 80 et 443, donc les constantes ne sont pas très utiles.

Voir aussi ce même post .

3
Christophe Roussy

Reportez-vous à http://docs.Oracle.com/javase/tutorial/networking/urls/urlInfo.html . C’est la couverture la plus concise sur l’analyse des URL. 

1
Satyajit Paul

Si votre serveur fonctionne derrière un serveur proxy, assurez-vous que votre en-tête de proxy est défini:

proxy_set_header X-Forwarded-Proto  $scheme;

Ensuite, pour obtenir le bon scheme & url, vous pouvez utiliser les classes de springframework:

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